libnavajo
web server for static and dynamic pages developement in C++
WebSocket.hh
Go to the documentation of this file.
1 //****************************************************************************
12 //****************************************************************************
13 
14 #ifndef WEBSOCKET_HH_
15 #define WEBSOCKET_HH_
16 
17 #include <algorithm>
18 #include <list>
19 #include <string>
20 
21 #include "libnavajo/WebServer.hh"
23 
24 // Max latency allowed is fixed to 500ms by default
25 #define CLIENTSENDING_MAXLATENCY_DEFAULT 500
26 
27 class WebSocket
28 {
29  std::list<WebSocketClient*> webSocketClientList;
30  pthread_mutex_t webSocketClientList_mutex;
31  bool useCompression;
32  bool useNaggleAlgo;
33  unsigned short clientSending_maxLatency;
34 
35  public:
36  WebSocket(bool compression=true): useCompression(compression), useNaggleAlgo(true),
37  clientSending_maxLatency(CLIENTSENDING_MAXLATENCY_DEFAULT)
38 
39  {
40  pthread_mutex_init(&webSocketClientList_mutex, NULL);
41  }
42 
43  ~WebSocket()
44  {
45  // Free all request, close all sockets
47  }
48 
53  virtual bool onOpening(HttpRequest* request) { return true; };
54 
59  virtual void onClosing(WebSocketClient* client) { };
60 
67  virtual void onTextMessage(WebSocketClient* client, const std::string &message, const bool fin)
68  { };
69 
77  virtual void onBinaryMessage(WebSocketClient* client, const unsigned char* message, size_t len, const bool fin)
78  { };
79 
86  virtual void onPongCtrlFrame(WebSocketClient* client, const unsigned char* message, size_t len)
87  { /* should check application data received is the same than in the ping message */ };
88 
96  virtual bool onPingCtrlFrame(WebSocketClient* client, const unsigned char* message, size_t len)
97  { return true; };
98 
104  virtual bool onCloseCtrlFrame(WebSocketClient* client, const unsigned char* message, size_t len)
105  { return true; };
106 
107 
113  inline void sendBroadcastTextMessage(const std::string &message, bool fin=true)
114  {
115  pthread_mutex_lock(&webSocketClientList_mutex);
116  for (std::list<WebSocketClient*>::iterator it = webSocketClientList.begin(); it != webSocketClientList.end(); it++)
117  (*it)->sendTextMessage(message, fin);
118  pthread_mutex_unlock(&webSocketClientList_mutex);
119  };
120 
127  inline void sendBroadcastBinaryMessage(const unsigned char *message, size_t length, bool fin = true)
128  {
129  pthread_mutex_lock(&webSocketClientList_mutex);
130  for (std::list<WebSocketClient*>::iterator it = webSocketClientList.begin(); it != webSocketClientList.end(); it++)
131  (*it)->sendBinaryMessage(message, length, fin);
132  pthread_mutex_unlock(&webSocketClientList_mutex);
133  };
134 
140  inline void sendBroadcastCloseCtrlFrame(const unsigned char *message, size_t length)
141  {
142  pthread_mutex_lock(&webSocketClientList_mutex);
143  for (std::list<WebSocketClient*>::iterator it = webSocketClientList.begin(); it != webSocketClientList.end(); it++)
144  (*it)->sendCloseCtrlFrame(message, length);
145  pthread_mutex_unlock(&webSocketClientList_mutex);
146  };
147 
152  inline void sendBroadcastCloseCtrlFrame(const std::string &reasonMsg = "")
153  {
154  sendBroadcastCloseCtrlFrame((const unsigned char*)reasonMsg.c_str(), reasonMsg.length());
155  }
156 
162  inline void sendBroadcastPingCtrlFrame(const unsigned char *message, size_t length)
163  {
164  pthread_mutex_lock(&webSocketClientList_mutex);
165  for (std::list<WebSocketClient*>::iterator it = webSocketClientList.begin(); it != webSocketClientList.end(); it++)
166  (*it)->sendPingCtrlFrame(message, length);
167  pthread_mutex_unlock(&webSocketClientList_mutex);
168  };
169 
174  inline void sendBroadcastPingCtrlFrame(const std::string &message)
175  {
176  sendBroadcastPingCtrlFrame((const unsigned char*)message.c_str(), message.length());
177  }
178 
184  inline void sendBroadcastPongCtrlFrame(const unsigned char *message, size_t length)
185  {
186  pthread_mutex_lock(&webSocketClientList_mutex);
187  for (std::list<WebSocketClient*>::iterator it = webSocketClientList.begin(); it != webSocketClientList.end(); it++)
188  (*it)->sendPongCtrlFrame(message, length);
189  pthread_mutex_unlock(&webSocketClientList_mutex);
190  }
191 
196  inline void sendBroadcastPongCtrlFrame(const std::string &message)
197  {
198  sendBroadcastPongCtrlFrame((const unsigned char*)message.c_str(), message.length());
199  }
200 
206  inline void newConnectionRequest(HttpRequest* request)
207  {
208  pthread_mutex_lock(&webSocketClientList_mutex);
209 
210  if (onOpening(request))
211  webSocketClientList.push_back(new WebSocketClient(this, request));
212  else
213  WebServer::freeClientSockData( request->getClientSockData() );
214 
215  pthread_mutex_unlock(&webSocketClientList_mutex);
216  };
217 
221  inline void removeAllClients()
222  {
223  pthread_mutex_lock(&webSocketClientList_mutex);
224  for (std::list<WebSocketClient*>::iterator it = webSocketClientList.begin(); it != webSocketClientList.end(); )
225  {
226  WebSocketClient *client=*it;
227  it++;
228  client->closeWS();
229  }
230  pthread_mutex_unlock(&webSocketClientList_mutex);
231  }
232 
238  inline void removeClient(WebSocketClient *client, bool cs=false)
239  {
240  if (!cs) pthread_mutex_lock(&webSocketClientList_mutex);
241  std::list<WebSocketClient*>::iterator it = std::find(webSocketClientList.begin(), webSocketClientList.end(), client);
242  if (it != webSocketClientList.end())
243  webSocketClientList.erase(it);
244  if(!cs) pthread_mutex_unlock(&webSocketClientList_mutex);
245  }
246 
251  inline void removeClient(HttpRequest *request)
252  {
253  pthread_mutex_lock(&webSocketClientList_mutex);
254  for (std::list<WebSocketClient*>::iterator it = webSocketClientList.begin(); it != webSocketClientList.end(); )
255  {
256  WebSocketClient *client=*it;
257  it++;
258  if (client->getHttpRequest() == request)
259  {
260  client->closeWS();
261  break;
262  }
263  }
264  pthread_mutex_unlock(&webSocketClientList_mutex);
265  }
266 
271  inline bool isUsingCompression()
272  {
273  return useCompression;
274  }
275 
280  inline void setUseCompression(bool compression)
281  {
282  useCompression = compression;
283  }
284 
285  inline bool isUsingNaggleAlgo()
286  {
287  return useNaggleAlgo;
288  }
289 
290  inline void setUseNaggleAlgo(bool naggle)
291  {
292  useNaggleAlgo=naggle;
293  }
294 
299  inline unsigned short getClientSendingMaxLatency()
300  {
301  return clientSending_maxLatency;
302  }
303 
308  inline void setClientSendingMaxLatency(unsigned short ms)
309  {
310  clientSending_maxLatency=ms;
311  }
312 
313 };
314 
315 #endif
316 
void setClientSendingMaxLatency(unsigned short ms)
Definition: WebSocket.hh:308
void sendBroadcastPongCtrlFrame(const std::string &message)
Definition: WebSocket.hh:196
ClientSockData * getClientSockData()
Definition: HttpRequest.hh:464
unsigned short getClientSendingMaxLatency()
Definition: WebSocket.hh:299
virtual bool onOpening(HttpRequest *request)
Definition: WebSocket.hh:53
void newConnectionRequest(HttpRequest *request)
Definition: WebSocket.hh:206
virtual void onClosing(WebSocketClient *client)
Definition: WebSocket.hh:59
void removeClient(WebSocketClient *client, bool cs=false)
Definition: WebSocket.hh:238
void sendBroadcastCloseCtrlFrame(const unsigned char *message, size_t length)
Definition: WebSocket.hh:140
WebServer.
Definition: WebSocketClient.hh:24
virtual void onBinaryMessage(WebSocketClient *client, const unsigned char *message, size_t len, const bool fin)
Definition: WebSocket.hh:77
virtual void onPongCtrlFrame(WebSocketClient *client, const unsigned char *message, size_t len)
Definition: WebSocket.hh:86
void sendBroadcastPongCtrlFrame(const unsigned char *message, size_t length)
Definition: WebSocket.hh:184
virtual bool onPingCtrlFrame(WebSocketClient *client, const unsigned char *message, size_t len)
Definition: WebSocket.hh:96
The WebSocket Client class.
Definition: HttpRequest.hh:42
void sendBroadcastPingCtrlFrame(const unsigned char *message, size_t length)
Definition: WebSocket.hh:162
void removeClient(HttpRequest *request)
Definition: WebSocket.hh:251
void sendBroadcastTextMessage(const std::string &message, bool fin=true)
Definition: WebSocket.hh:113
void sendBroadcastBinaryMessage(const unsigned char *message, size_t length, bool fin=true)
Definition: WebSocket.hh:127
bool isUsingCompression()
Definition: WebSocket.hh:271
virtual bool onCloseCtrlFrame(WebSocketClient *client, const unsigned char *message, size_t len)
Definition: WebSocket.hh:104
void setUseCompression(bool compression)
Definition: WebSocket.hh:280
void sendBroadcastPingCtrlFrame(const std::string &message)
Definition: WebSocket.hh:174
Definition: WebSocket.hh:27
virtual void onTextMessage(WebSocketClient *client, const std::string &message, const bool fin)
Definition: WebSocket.hh:67
void removeAllClients()
Definition: WebSocket.hh:221
void sendBroadcastCloseCtrlFrame(const std::string &reasonMsg="")
Definition: WebSocket.hh:152