Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

Commit 2f37037

Browse files
matt123pme-no-dev
authored andcommitted
Add function so that the total number of web-socket clients can be limited (#591)
* Add function so that the total number of web-socket clients can be limited easily. This is to cope with a problem when a browser does not close the web-socket connection correctly. I have observed this on Chromium based browsers. The memory leak will eventually lead to the server crashing. Normally only one connection per client is required, so limiting the number of connections would not normally cause any problems. * Prevent an assertion failure when using WebSockets Frequently when using Web Sockets you will get the assert failure: assertion "new_rcv_ann_wnd <= 0xffff" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/lwip/src/core/tcp.c", line 779, function: tcp_update_rcv_ann_wnd This will happen particulary when you close the browser window. This change prevents the issue from occuring. * Do not use thread locking with the ESP8266, but instead use an empty placeholder class that can be used to implement locking at a later date. * Do not use thread locking with the ESP8266, but instead use an empty placeholder class that can be used to implement locking at a later date. * Add function so that the total number of web-socket clients can be limited easily. This is to cope with a problem when a browser does not close the web-socket connection correctly. I have observed this on Chromium based browsers. The memory leak will eventually lead to the server crashing. Normally only one connection per client is required, so limiting the number of connections would not normally cause any problems. * Set the default number of ws clients dependent on processor.
1 parent f5ee193 commit 2f37037

File tree

4 files changed

+26
-0
lines changed

4 files changed

+26
-0
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht
7979
- [Async WebSocket Event](#async-websocket-event)
8080
- [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client)
8181
- [Direct access to web socket message buffer](#direct-access-to-web-socket-message-buffer)
82+
- [Limiting the number of web socket clients](#limiting-the-number-of-web-socket-clients)
8283
- [Async Event Source Plugin](#async-event-source-plugin)
8384
- [Setup Event Source on the server](#setup-event-source-on-the-server)
8485
- [Setup Event Source in the browser](#setup-event-source-in-the-browser)
@@ -1126,6 +1127,16 @@ void sendDataWs(AsyncWebSocketClient * client)
11261127
}
11271128
```
11281129

1130+
### Limiting the number of web socket clients
1131+
Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript. This will eventually exhaust the web server's resources and will cause the server to crash. Periodically calling the cleanClients() function from the main loop() function limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can called be every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient.
1132+
1133+
```cpp
1134+
void loop(){
1135+
ws.cleanupClients();
1136+
}
1137+
```
1138+
1139+
11291140
## Async Event Source Plugin
11301141
The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser.
11311142
Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol.

examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,4 +217,5 @@ void setup(){
217217

218218
void loop(){
219219
ArduinoOTA.handle();
220+
ws.cleanupClients();
220221
}

src/AsyncWebSocket.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,13 @@ void AsyncWebSocket::closeAll(uint16_t code, const char * message){
927927
}
928928
}
929929

930+
void AsyncWebSocket::cleanupClients(uint16_t maxClients)
931+
{
932+
if (count() > maxClients){
933+
_clients.front()->close();
934+
}
935+
}
936+
930937
void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){
931938
AsyncWebSocketClient * c = client(id);
932939
if(c)

src/AsyncWebSocket.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
#include <Hash.h>
3838
#endif
3939

40+
#ifdef ESP32
41+
#define DEFAULT_MAX_WS_CLIENTS 8
42+
#else
43+
#define DEFAULT_MAX_WS_CLIENTS 4
44+
#endif
45+
4046
class AsyncWebSocket;
4147
class AsyncWebSocketResponse;
4248
class AsyncWebSocketClient;
@@ -255,6 +261,7 @@ class AsyncWebSocket: public AsyncWebHandler {
255261

256262
void close(uint32_t id, uint16_t code=0, const char * message=NULL);
257263
void closeAll(uint16_t code=0, const char * message=NULL);
264+
void cleanupClients(uint16_t maxClients = DEFAULT_MAX_WS_CLIENTS);
258265

259266
void ping(uint32_t id, uint8_t *data=NULL, size_t len=0);
260267
void pingAll(uint8_t *data=NULL, size_t len=0); // done

0 commit comments

Comments
 (0)