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 
16 extern "C" {
17 #include "ws_parser/ws_parser.h"
18 }
19 
26 #define WEBSOCKET_VERSION 13 // 1.3
27 
28 DECLARE_FSTR(WSSTR_CONNECTION)
29 DECLARE_FSTR(WSSTR_UPGRADE)
30 DECLARE_FSTR(WSSTR_WEBSOCKET)
31 DECLARE_FSTR(WSSTR_HOST)
32 DECLARE_FSTR(WSSTR_ORIGIN)
33 DECLARE_FSTR(WSSTR_KEY)
34 DECLARE_FSTR(WSSTR_PROTOCOL)
35 DECLARE_FSTR(WSSTR_VERSION)
36 DECLARE_FSTR(WSSTR_SECRET)
37 
39 
41 
45 
53 };
54 
55 struct WsFrameInfo {
56  ws_frame_type_t type = WS_FRAME_TEXT;
57  char* payload = nullptr;
58  size_t payloadLength = 0;
59 
60  WsFrameInfo() = default;
61 
62  WsFrameInfo(ws_frame_type_t type, char* payload, size_t payloadLength)
63  : type(type), payload(payload), payloadLength(payloadLength)
64  {
65  }
66 };
67 
69 {
70 public:
76  WebsocketConnection(HttpConnection* connection, bool isClientConnection = true);
77 
79  {
80  close();
81  }
82 
89  bool bind(HttpRequest& request, HttpResponse& response);
90 
97  bool send(const char* message, size_t length, ws_frame_type_t type = WS_FRAME_TEXT);
98 
105  bool send(const String& message, ws_frame_type_t type = WS_FRAME_TEXT)
106  {
107  return send(message.c_str(), message.length(), type);
108  }
109 
119  bool send(IDataSourceStream* stream, ws_frame_type_t type = WS_FRAME_TEXT, bool useMask = false, bool isFin = true);
120 
127  static void broadcast(const char* message, size_t length, ws_frame_type_t type = WS_FRAME_TEXT);
128 
134  static void broadcast(const String& message, ws_frame_type_t type = WS_FRAME_TEXT)
135  {
136  broadcast(message.c_str(), message.length(), type);
137  }
138 
143  bool sendString(const String& message)
144  {
145  return send(message, WS_FRAME_TEXT);
146  }
147 
153  bool sendBinary(const uint8_t* data, size_t length)
154  {
155  return send(reinterpret_cast<const char*>(data), length, WS_FRAME_BINARY);
156  }
157 
161  void close();
162 
166  void reset();
167 
172  void setUserData(void* userData)
173  {
174  this->userData = userData;
175  }
176 
181  void* getUserData()
182  {
183  return userData;
184  }
185 
190  bool operator==(const WebsocketConnection& rhs) const
191  {
192  return (this == &rhs);
193  }
194 
201  {
202  return websocketList;
203  }
204 
210  {
211  wsConnect = handler;
212  }
213 
219  {
220  wsMessage = handler;
221  }
222 
228  {
229  wsBinary = handler;
230  }
236  {
237  wsPong = handler;
238  }
244  {
245  wsDisconnect = handler;
246  }
247 
252  void activate();
253 
258  bool onConnected();
259 
265  {
266  return connection;
267  }
268 
274  void setConnection(HttpConnection* connection, bool isClientConnection = true)
275  {
276  this->connection = connection;
277  this->isClientConnection = isClientConnection;
278  }
279 
284  {
285  return state;
286  }
287 
288 protected:
289  // Static handlers for ws_parser
290  static int staticOnDataBegin(void* userData, ws_frame_type_t type);
291  static int staticOnDataPayload(void* userData, const char* at, size_t length);
292  static int staticOnDataEnd(void* userData);
293  static int staticOnControlBegin(void* userData, ws_frame_type_t type);
294  static int staticOnControlPayload(void* userData, const char*, size_t length);
295  static int staticOnControlEnd(void* userData);
296 
303  bool processFrame(TcpClient& client, char* at, int size);
304 
305 protected:
306  WebsocketDelegate wsConnect = nullptr;
307  WebsocketMessageDelegate wsMessage = nullptr;
308  WebsocketBinaryDelegate wsBinary = nullptr;
309  WebsocketDelegate wsPong = nullptr;
310  WebsocketDelegate wsDisconnect = nullptr;
311 
312  void* userData = nullptr;
313 
315 
316 private:
317  ws_frame_type_t frameType = WS_FRAME_TEXT;
318  WsFrameInfo controlFrame;
319 
320  ws_parser_t parser;
321  static const ws_parser_callbacks_t parserSettings;
322 
323  static WebsocketList websocketList;
324 
325  bool isClientConnection = true;
326 
327  HttpConnection* connection = nullptr;
328  bool activated = false;
329 };
330 
bool sendBinary(const uint8_t *data, size_t length)
Sends a binary websocket message.
Definition: WebsocketConnection.h:153
WsFrameInfo()=default
HttpConnection * getConnection()
Gets the underlying HTTP connection.
Definition: WebsocketConnection.h:264
void setUserData(void *userData)
Attaches a user data to a websocket connection.
Definition: WebsocketConnection.h:172
Definition: WebsocketConnection.h:68
WsFrameInfo(ws_frame_type_t type, char *payload, size_t payloadLength)
Definition: WebsocketConnection.h:62
size_t payloadLength
Definition: WebsocketConnection.h:58
const char * c_str() const
Get a constant (un-modifiable) pointer to String content.
Definition: WString.h:616
Base class for read-only stream.
Definition: DataSourceStream.h:45
Vector class template.
Definition: WVector.h:31
bool operator==(const WebsocketConnection &rhs) const
Test if another connection refers to the same object.
Definition: WebsocketConnection.h:190
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:134
Definition: WebsocketConnection.h:55
bool send(const String &message, ws_frame_type_t type=WS_FRAME_TEXT)
Sends websocket message from a String.
Definition: WebsocketConnection.h:105
The String class.
Definition: WString.h:136
Definition: TcpClient.h:46
char * payload
Definition: WebsocketConnection.h:57
#define DECLARE_FSTR(name)
Declare a global FSTR::String& reference.
Definition: String.hpp:63
void setBinaryHandler(WebsocketBinaryDelegate handler)
Sets the callback handler to be called after a binary websocket message is received.
Definition: WebsocketConnection.h:227
ws_frame_type_t type
Definition: WebsocketConnection.h:56
size_t length(void) const
Obtain the String length in characters, excluding NUL terminator.
Definition: WString.h:243
WsConnectionState
Current state of Websocket connection.
Definition: WebsocketConnection.h:49
WsConnectionState getState()
Gets the state of the websocket connection.
Definition: WebsocketConnection.h:283
void setConnectionHandler(WebsocketDelegate handler)
Sets the callback handler to be called after successful websocket connection.
Definition: WebsocketConnection.h:209
void setDisconnectionHandler(WebsocketDelegate handler)
Sets the callback handler to be called before closing a websocket connection.
Definition: WebsocketConnection.h:243
bool sendString(const String &message)
Sends a string websocket message.
Definition: WebsocketConnection.h:143
Encapsulates an incoming or outgoing request.
Definition: HttpRequest.h:36
Definition: WebsocketConnection.h:51
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:235
Definition: WebsocketConnection.h:50
void setConnection(HttpConnection *connection, bool isClientConnection=true)
Sets the underlying (transport ) HTTP connection.
Definition: WebsocketConnection.h:274
static const WebsocketList & getActiveWebsockets()
Obtain the list of active websockets.
Definition: WebsocketConnection.h:200
void * getUserData()
Retrieves user data attached.
Definition: WebsocketConnection.h:181
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:218
Definition: WebsocketConnection.h:52
virtual ~WebsocketConnection()
Definition: WebsocketConnection.h:78