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 
39 typedef Vector<WebsocketConnection*> WebsocketList;
40 
41 typedef Delegate<void(WebsocketConnection&)> WebsocketDelegate;
42 typedef Delegate<void(WebsocketConnection&, const String&)> WebsocketMessageDelegate;
43 typedef Delegate<void(WebsocketConnection&, uint8_t* data, size_t size)> WebsocketBinaryDelegate;
44 
46 
47 struct WsFrameInfo {
48  ws_frame_type_t type = WS_FRAME_TEXT;
49  char* payload = nullptr;
50  size_t payloadLength = 0;
51 
52  WsFrameInfo() = default;
53 
54  WsFrameInfo(ws_frame_type_t type, char* payload, size_t payloadLength)
55  : type(type), payload(payload), payloadLength(payloadLength)
56  {
57  }
58 };
59 
61 {
62 public:
68  WebsocketConnection(HttpConnection* connection, bool isClientConnection = true);
69 
71  {
72  state = eWSCS_Closed;
73  close();
74  }
75 
82  bool bind(HttpRequest& request, HttpResponse& response);
83 
90  virtual void send(const char* message, size_t length, ws_frame_type_t type = WS_FRAME_TEXT);
91 
98  void send(const String& message, ws_frame_type_t type = WS_FRAME_TEXT)
99  {
100  send(message.c_str(), message.length(), type);
101  }
102 
109  static void broadcast(const char* message, size_t length, ws_frame_type_t type = WS_FRAME_TEXT);
110 
116  static void broadcast(const String& message, ws_frame_type_t type = WS_FRAME_TEXT)
117  {
118  broadcast(message.c_str(), message.length(), type);
119  }
120 
125  void sendString(const String& message)
126  {
127  send(message, WS_FRAME_TEXT);
128  }
129 
135  void sendBinary(const uint8_t* data, size_t length)
136  {
137  send(reinterpret_cast<const char*>(data), length, WS_FRAME_BINARY);
138  }
139 
143  void close();
144 
148  void reset();
149 
154  void setUserData(void* userData)
155  {
156  this->userData = userData;
157  }
158 
163  void* getUserData()
164  {
165  return userData;
166  }
167 
172  bool operator==(const WebsocketConnection& rhs) const
173  {
174  return (this == &rhs);
175  }
176 
183  {
184  return websocketList;
185  }
186 
192  {
193  wsConnect = handler;
194  }
195 
201  {
202  wsMessage = handler;
203  }
204 
210  {
211  wsBinary = handler;
212  }
213 
219  {
220  wsDisconnect = handler;
221  }
222 
227  void activate();
228 
233  bool onConnected();
234 
240  {
241  return connection;
242  }
243 
249  void setConnection(HttpConnection* connection, bool isClientConnection = true)
250  {
251  this->connection = connection;
252  this->isClientConnection = isClientConnection;
253  }
254 
259  {
260  return state;
261  }
262 
263 protected:
264  // Static handlers for ws_parser
265  static int staticOnDataBegin(void* userData, ws_frame_type_t type);
266  static int staticOnDataPayload(void* userData, const char* at, size_t length);
267  static int staticOnDataEnd(void* userData);
268  static int staticOnControlBegin(void* userData, ws_frame_type_t type);
269  static int staticOnControlPayload(void* userData, const char*, size_t length);
270  static int staticOnControlEnd(void* userData);
271 
278  bool processFrame(TcpClient& client, char* at, int size);
279 
290  size_t encodeFrame(ws_frame_type_t type, const char* inData, size_t inLength, char* outData, size_t outLength,
291  bool useMask = true, bool isFin = true);
292 
293 protected:
294  WebsocketDelegate wsConnect = nullptr;
295  WebsocketMessageDelegate wsMessage = nullptr;
296  WebsocketBinaryDelegate wsBinary = nullptr;
297  WebsocketDelegate wsDisconnect = nullptr;
298 
299  void* userData = nullptr;
300 
302 
303 private:
304  ws_frame_type_t frameType = WS_FRAME_TEXT;
305  WsFrameInfo controlFrame;
306 
307  ws_parser_t parser;
308  static const ws_parser_callbacks_t parserSettings;
309 
310  static WebsocketList websocketList;
311 
312  bool isClientConnection = true;
313 
314  HttpConnection* connection = nullptr;
315  bool activated = false;
316 };
317 
WsFrameInfo()=default
HttpConnection * getConnection()
Gets the underlying HTTP connection.
Definition: WebsocketConnection.h:239
void setUserData(void *userData)
Attaches a user data to a websocket connection.
Definition: WebsocketConnection.h:154
Definition: WebsocketConnection.h:60
WsFrameInfo(ws_frame_type_t type, char *payload, size_t payloadLength)
Definition: WebsocketConnection.h:54
size_t payloadLength
Definition: WebsocketConnection.h:50
const char * c_str() const
Get a constant (un-modifiable) pointer to String content.
Definition: WString.h:600
void send(const String &message, ws_frame_type_t type=WS_FRAME_TEXT)
Sends websocket message from a String.
Definition: WebsocketConnection.h:98
void sendString(const String &message)
Sends a string websocket message.
Definition: WebsocketConnection.h:125
Vector class template.
Definition: WVector.h:29
bool operator==(const WebsocketConnection &rhs) const
Test if another connection refers to the same object.
Definition: WebsocketConnection.h:172
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:116
Definition: WebsocketConnection.h:47
The String class.
Definition: WString.h:136
Definition: TcpClient.h:46
Definition: Delegate.h:20
char * payload
Definition: WebsocketConnection.h:49
#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:135
void setBinaryHandler(WebsocketBinaryDelegate handler)
Sets the callback handler to be called after a binary websocket message is received.
Definition: WebsocketConnection.h:209
ws_frame_type_t type
Definition: WebsocketConnection.h:48
size_t length(void) const
Obtain the String length in characters, excluding NUL terminator.
Definition: WString.h:228
WsConnectionState
Definition: WebsocketConnection.h:45
WsConnectionState getState()
Gets the state of the websocket connection.
Definition: WebsocketConnection.h:258
void setConnectionHandler(WebsocketDelegate handler)
Sets the callback handler to be called after successful websocket connection.
Definition: WebsocketConnection.h:191
void setDisconnectionHandler(WebsocketDelegate handler)
Sets the callback handler to be called before closing a websocket connection.
Definition: WebsocketConnection.h:218
Definition: HttpRequest.h:35
Definition: WebsocketConnection.h:45
Provides http base used for client and server connections.
Definition: HttpConnection.h:27
Definition: WebsocketConnection.h:45
void setConnection(HttpConnection *connection, bool isClientConnection=true)
Sets the underlying (transport ) HTTP connection.
Definition: WebsocketConnection.h:249
static const WebsocketList & getActiveWebsockets()
Obtain the list of active websockets.
Definition: WebsocketConnection.h:182
void * getUserData()
Retrieves user data attached.
Definition: WebsocketConnection.h:163
Definition: HttpResponse.h:20
void setMessageHandler(WebsocketMessageDelegate handler)
Sets the callback handler to be called after a websocket message is received.
Definition: WebsocketConnection.h:200
Definition: WebsocketConnection.h:45
virtual ~WebsocketConnection()
Definition: WebsocketConnection.h:70