WebsocketConnection.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * WebsocketConnection.h
8  *
9  ****/
10 
11 #pragma once
12 
13 #include "Network/TcpServer.h"
14 #include "../HttpConnection.h"
15 extern "C" {
16 #include "ws_parser/ws_parser.h"
17 }
18 
25 #define WEBSOCKET_VERSION 13 // 1.3
26 
27 DECLARE_FSTR(WSSTR_CONNECTION)
28 DECLARE_FSTR(WSSTR_UPGRADE)
29 DECLARE_FSTR(WSSTR_WEBSOCKET)
30 DECLARE_FSTR(WSSTR_HOST)
31 DECLARE_FSTR(WSSTR_ORIGIN)
32 DECLARE_FSTR(WSSTR_KEY)
33 DECLARE_FSTR(WSSTR_PROTOCOL)
34 DECLARE_FSTR(WSSTR_VERSION)
35 DECLARE_FSTR(WSSTR_SECRET)
36 
38 
40 
44 
49 };
50 
51 struct WsFrameInfo {
52  ws_frame_type_t type = WS_FRAME_TEXT;
53  char* payload = nullptr;
54  size_t payloadLength = 0;
55 
56  WsFrameInfo() = default;
57 
58  WsFrameInfo(ws_frame_type_t type, char* payload, size_t payloadLength)
59  : type(type), payload(payload), payloadLength(payloadLength)
60  {
61  }
62 };
63 
65 {
66 public:
72  WebsocketConnection(HttpConnection* connection, bool isClientConnection = true);
73 
75  {
76  close();
77  }
78 
85  bool bind(HttpRequest& request, HttpResponse& response);
86 
93  virtual void send(const char* message, size_t length, ws_frame_type_t type = WS_FRAME_TEXT);
94 
101  void send(const String& message, ws_frame_type_t type = WS_FRAME_TEXT)
102  {
103  send(message.c_str(), message.length(), type);
104  }
105 
112  static void broadcast(const char* message, size_t length, ws_frame_type_t type = WS_FRAME_TEXT);
113 
119  static void broadcast(const String& message, ws_frame_type_t type = WS_FRAME_TEXT)
120  {
121  broadcast(message.c_str(), message.length(), type);
122  }
123 
128  void sendString(const String& message)
129  {
130  send(message, WS_FRAME_TEXT);
131  }
132 
138  void sendBinary(const uint8_t* data, size_t length)
139  {
140  send(reinterpret_cast<const char*>(data), length, WS_FRAME_BINARY);
141  }
142 
146  void close();
147 
151  void reset();
152 
157  void setUserData(void* userData)
158  {
159  this->userData = userData;
160  }
161 
166  void* getUserData()
167  {
168  return userData;
169  }
170 
175  bool operator==(const WebsocketConnection& rhs) const
176  {
177  return (this == &rhs);
178  }
179 
186  {
187  return websocketList;
188  }
189 
195  {
196  wsConnect = handler;
197  }
198 
204  {
205  wsMessage = handler;
206  }
207 
213  {
214  wsBinary = handler;
215  }
221  {
222  wsPong = handler;
223  }
229  {
230  wsDisconnect = handler;
231  }
232 
237  void activate();
238 
243  bool onConnected();
244 
250  {
251  return connection;
252  }
253 
259  void setConnection(HttpConnection* connection, bool isClientConnection = true)
260  {
261  this->connection = connection;
262  this->isClientConnection = isClientConnection;
263  }
264 
269  {
270  return state;
271  }
272 
273 protected:
274  // Static handlers for ws_parser
275  static int staticOnDataBegin(void* userData, ws_frame_type_t type);
276  static int staticOnDataPayload(void* userData, const char* at, size_t length);
277  static int staticOnDataEnd(void* userData);
278  static int staticOnControlBegin(void* userData, ws_frame_type_t type);
279  static int staticOnControlPayload(void* userData, const char*, size_t length);
280  static int staticOnControlEnd(void* userData);
281 
288  bool processFrame(TcpClient& client, char* at, int size);
289 
300  size_t encodeFrame(ws_frame_type_t type, const char* inData, size_t inLength, char* outData, size_t outLength,
301  bool useMask = true, bool isFin = true);
302 
303 protected:
304  WebsocketDelegate wsConnect = nullptr;
305  WebsocketMessageDelegate wsMessage = nullptr;
306  WebsocketBinaryDelegate wsBinary = nullptr;
307  WebsocketDelegate wsPong = nullptr;
308  WebsocketDelegate wsDisconnect = nullptr;
309 
310  void* userData = nullptr;
311 
313 
314 private:
315  ws_frame_type_t frameType = WS_FRAME_TEXT;
316  WsFrameInfo controlFrame;
317 
318  ws_parser_t parser;
319  static const ws_parser_callbacks_t parserSettings;
320 
321  static WebsocketList websocketList;
322 
323  bool isClientConnection = true;
324 
325  HttpConnection* connection = nullptr;
326  bool activated = false;
327 };
328 
WsFrameInfo()=default
HttpConnection * getConnection()
Gets the underlying HTTP connection.
Definition: WebsocketConnection.h:249
void setUserData(void *userData)
Attaches a user data to a websocket connection.
Definition: WebsocketConnection.h:157
Definition: WebsocketConnection.h:64
WsFrameInfo(ws_frame_type_t type, char *payload, size_t payloadLength)
Definition: WebsocketConnection.h:58
size_t payloadLength
Definition: WebsocketConnection.h:54
const char * c_str() const
Get a constant (un-modifiable) pointer to String content.
Definition: WString.h:641
void send(const String &message, ws_frame_type_t type=WS_FRAME_TEXT)
Sends websocket message from a String.
Definition: WebsocketConnection.h:101
void sendString(const String &message)
Sends a string websocket message.
Definition: WebsocketConnection.h:128
Vector class template.
Definition: WVector.h:30
bool operator==(const WebsocketConnection &rhs) const
Test if another connection refers to the same object.
Definition: WebsocketConnection.h:175
static void broadcast(const String &message, ws_frame_type_t type=WS_FRAME_TEXT)
Broadcasts a message to all active websocket connections.
Definition: WebsocketConnection.h:119
Definition: WebsocketConnection.h:51
The String class.
Definition: WString.h:136
Definition: TcpClient.h:46
char * payload
Definition: WebsocketConnection.h:53
#define DECLARE_FSTR(name)
Declare a global FSTR::String& reference.
Definition: String.hpp:63
void sendBinary(const uint8_t *data, size_t length)
Sends a binary websocket message.
Definition: WebsocketConnection.h:138
void setBinaryHandler(WebsocketBinaryDelegate handler)
Sets the callback handler to be called after a binary websocket message is received.
Definition: WebsocketConnection.h:212
ws_frame_type_t type
Definition: WebsocketConnection.h:52
size_t length(void) const
Obtain the String length in characters, excluding NUL terminator.
Definition: WString.h:237
WsConnectionState
Definition: WebsocketConnection.h:45
WsConnectionState getState()
Gets the state of the websocket connection.
Definition: WebsocketConnection.h:268
void setConnectionHandler(WebsocketDelegate handler)
Sets the callback handler to be called after successful websocket connection.
Definition: WebsocketConnection.h:194
void setDisconnectionHandler(WebsocketDelegate handler)
Sets the callback handler to be called before closing a websocket connection.
Definition: WebsocketConnection.h:228
Encapsulates an incoming or outgoing request.
Definition: HttpRequest.h:36
Definition: WebsocketConnection.h:47
Provides http base used for client and server connections.
Definition: HttpConnection.h:27
void setPongHandler(WebsocketDelegate handler)
Sets the callback handler to be called when pong reply received.
Definition: WebsocketConnection.h:220
Definition: WebsocketConnection.h:46
void setConnection(HttpConnection *connection, bool isClientConnection=true)
Sets the underlying (transport ) HTTP connection.
Definition: WebsocketConnection.h:259
static const WebsocketList & getActiveWebsockets()
Obtain the list of active websockets.
Definition: WebsocketConnection.h:185
void * getUserData()
Retrieves user data attached.
Definition: WebsocketConnection.h:166
Represents either an incoming or outgoing response to a HTTP request.
Definition: HttpResponse.h:25
void setMessageHandler(WebsocketMessageDelegate handler)
Sets the callback handler to be called after a websocket message is received.
Definition: WebsocketConnection.h:203
Definition: WebsocketConnection.h:48
virtual ~WebsocketConnection()
Definition: WebsocketConnection.h:74