Skip to content

Commit c3e4ca1

Browse files
committed
Replace use of LinkedList<T> with std::list for AsyncWebServer clients
Fraction of commit 8bb1c70 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Const-ify a few methods of AsyncWebServer. Instead of using the new operator to create the AsyncWebSocketClient and then discarding it while adding the pointer to the client list, just create the client inside the standard list container. Workarounds for lack of auto parameter support in lambdas used by original patch.
1 parent 380ead2 commit c3e4ca1

File tree

2 files changed

+68
-68
lines changed

2 files changed

+68
-68
lines changed

src/AsyncWebSocket.cpp

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,6 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async
540540
_client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this);
541541
_client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this);
542542
_client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this);
543-
_server->_addClient(this);
544543
_server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0);
545544
delete request;
546545
memset(&_pinfo,0,sizeof(_pinfo));
@@ -614,9 +613,8 @@ void AsyncWebSocketClient::_runQueue(){
614613
_clearQueue();
615614
}
616615

617-
bool AsyncWebSocketClient::queueIsFull(){
618-
if((_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED) ) return true;
619-
return false;
616+
bool AsyncWebSocketClient::queueIsFull() const {
617+
return (_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED);
620618
}
621619

622620
void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){
@@ -909,14 +907,14 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer)
909907
_queueMessage(new AsyncWebSocketMultiMessage(buffer, WS_BINARY));
910908
}
911909

912-
IPAddress AsyncWebSocketClient::remoteIP() {
910+
IPAddress AsyncWebSocketClient::remoteIP() const {
913911
if(!_client) {
914912
return IPAddress(0U);
915913
}
916914
return _client->remoteIP();
917915
}
918916

919-
uint16_t AsyncWebSocketClient::remotePort() {
917+
uint16_t AsyncWebSocketClient::remotePort() const {
920918
if(!_client) {
921919
return 0;
922920
}
@@ -931,7 +929,6 @@ uint16_t AsyncWebSocketClient::remotePort() {
931929

932930
AsyncWebSocket::AsyncWebSocket(const String& url)
933931
:_url(url)
934-
,_clients(LinkedList<AsyncWebSocketClient *>([](AsyncWebSocketClient *c){ delete c; }))
935932
,_cNextId(1)
936933
,_enabled(true)
937934
{
@@ -946,64 +943,65 @@ void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType ty
946943
}
947944
}
948945

949-
void AsyncWebSocket::_addClient(AsyncWebSocketClient * client){
950-
_clients.add(client);
946+
AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request)
947+
{
948+
_clients.emplace_back(request, this);
949+
return &_clients.back();
951950
}
952951

953952
void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient * client){
954-
955-
_clients.remove_first([=](AsyncWebSocketClient * c){
956-
return c->id() == client->id();
957-
});
953+
const auto client_id = client->id();
954+
const auto iter = std::find_if(std::begin(_clients), std::end(_clients),
955+
[client_id](const AsyncWebSocketClient &c){ return c.id() == client_id; });
956+
if (iter != std::end(_clients))
957+
_clients.erase(iter);
958958
}
959959

960960
bool AsyncWebSocket::availableForWriteAll(){
961-
for(const auto& c: _clients){
962-
if(c->queueIsFull()) return false;
963-
}
964-
return true;
961+
return std::none_of(std::begin(_clients), std::end(_clients),
962+
[](const AsyncWebSocketClient &c){ return c.queueIsFull(); });
965963
}
966964

967965
bool AsyncWebSocket::availableForWrite(uint32_t id){
968-
for(const auto& c: _clients){
969-
if(c->queueIsFull() && (c->id() == id )) return false;
970-
}
971-
return true;
966+
const auto iter = std::find_if(std::begin(_clients), std::end(_clients),
967+
[id](const AsyncWebSocketClient &c){ return c.id() == id; });
968+
if (iter == std::end(_clients))
969+
return true; // don't know why me-no-dev decided like this?
970+
return !iter->queueIsFull();
972971
}
973972

974973
size_t AsyncWebSocket::count() const {
975-
return _clients.count_if([](AsyncWebSocketClient * c){
976-
return c->status() == WS_CONNECTED;
977-
});
974+
return std::count_if(std::begin(_clients), std::end(_clients),
975+
[](const AsyncWebSocketClient &c){ return c.status() == WS_CONNECTED; });
978976
}
979977

980978
AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id){
981-
for(const auto &c: _clients){
982-
if(c->id() == id && c->status() == WS_CONNECTED){
983-
return c;
984-
}
985-
}
986-
return nullptr;
979+
const auto iter = std::find_if(std::begin(_clients), std::end(_clients),
980+
[id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; });
981+
if (iter == std::end(_clients))
982+
return nullptr;
983+
984+
return &(*iter);
987985
}
988986

989987

990988
void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){
991-
AsyncWebSocketClient * c = client(id);
992-
if(c)
989+
AsyncWebSocketClient *c = client(id);
990+
if (c)
993991
c->close(code, message);
994992
}
995993

996994
void AsyncWebSocket::closeAll(uint16_t code, const char * message){
997-
for(const auto& c: _clients){
998-
if(c->status() == WS_CONNECTED)
999-
c->close(code, message);
995+
for(auto& c: _clients){
996+
if(c.status() == WS_CONNECTED)
997+
c.close(code, message);
1000998
}
1001999
}
10021000

10031001
void AsyncWebSocket::cleanupClients(uint16_t maxClients)
10041002
{
10051003
if (count() > maxClients){
1006-
_clients.front()->close();
1004+
_clients.front().close();
10071005
}
10081006
}
10091007

@@ -1014,24 +1012,24 @@ void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){
10141012
}
10151013

10161014
void AsyncWebSocket::pingAll(uint8_t *data, size_t len){
1017-
for(const auto& c: _clients){
1018-
if(c->status() == WS_CONNECTED)
1019-
c->ping(data, len);
1015+
for(auto& c: _clients){
1016+
if(c.status() == WS_CONNECTED)
1017+
c.ping(data, len);
10201018
}
10211019
}
10221020

10231021
void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){
1024-
AsyncWebSocketClient * c = client(id);
1022+
AsyncWebSocketClient *c = client(id);
10251023
if(c)
10261024
c->text(message, len);
10271025
}
10281026

10291027
void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer){
10301028
if (!buffer) return;
10311029
buffer->lock();
1032-
for(const auto& c: _clients){
1033-
if(c->status() == WS_CONNECTED){
1034-
c->text(buffer);
1030+
for(auto& c: _clients){
1031+
if(c.status() == WS_CONNECTED){
1032+
c.text(buffer);
10351033
}
10361034
}
10371035
buffer->unlock();
@@ -1060,24 +1058,24 @@ void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer)
10601058
{
10611059
if (!buffer) return;
10621060
buffer->lock();
1063-
for(const auto& c: _clients){
1064-
if(c->status() == WS_CONNECTED)
1065-
c->binary(buffer);
1061+
for(auto& c: _clients){
1062+
if(c.status() == WS_CONNECTED)
1063+
c.binary(buffer);
10661064
}
10671065
buffer->unlock();
10681066
_cleanBuffers();
10691067
}
10701068

10711069
void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessage *message){
1072-
AsyncWebSocketClient * c = client(id);
1073-
if(c)
1070+
AsyncWebSocketClient *c = client(id);
1071+
if (c)
10741072
c->message(message);
10751073
}
10761074

10771075
void AsyncWebSocket::messageAll(AsyncWebSocketMultiMessage *message){
1078-
for(const auto& c: _clients){
1079-
if(c->status() == WS_CONNECTED)
1080-
c->message(message);
1076+
for(auto& c: _clients){
1077+
if(c.status() == WS_CONNECTED)
1078+
c.message(message);
10811079
}
10821080
_cleanBuffers();
10831081
}
@@ -1186,9 +1184,9 @@ void AsyncWebSocket::textAll(const String &message){
11861184
textAll(message.c_str(), message.length());
11871185
}
11881186
void AsyncWebSocket::textAll(const __FlashStringHelper *message){
1189-
for(const auto& c: _clients){
1190-
if(c->status() == WS_CONNECTED)
1191-
c->text(message);
1187+
for(auto& c: _clients){
1188+
if(c.status() == WS_CONNECTED)
1189+
c.text(message);
11921190
}
11931191
}
11941192
void AsyncWebSocket::binary(uint32_t id, const char * message){
@@ -1221,9 +1219,9 @@ void AsyncWebSocket::binaryAll(const String &message){
12211219
binaryAll(message.c_str(), message.length());
12221220
}
12231221
void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){
1224-
for(const auto& c: _clients){
1225-
if(c->status() == WS_CONNECTED)
1226-
c-> binary(message, len);
1222+
for(auto& c: _clients){
1223+
if(c.status() == WS_CONNECTED)
1224+
c.binary(message, len);
12271225
}
12281226
}
12291227

@@ -1333,7 +1331,7 @@ void AsyncWebSocket::_cleanBuffers()
13331331
}
13341332
}
13351333

1336-
AsyncWebSocket::AsyncWebSocketClientLinkedList AsyncWebSocket::getClients() const {
1334+
const AsyncWebSocket::AsyncWebSocketClientLinkedList &AsyncWebSocket::getClients() const {
13371335
return _clients;
13381336
}
13391337

@@ -1391,7 +1389,7 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request){
13911389
size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){
13921390
(void)time;
13931391
if(len){
1394-
new AsyncWebSocketClient(request, _server);
1392+
_server->_newClient(request);
13951393
}
13961394
return 0;
13971395
}

src/AsyncWebSocket.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,14 +184,16 @@ class AsyncWebSocketClient {
184184
~AsyncWebSocketClient();
185185

186186
//client id increments for the given server
187-
uint32_t id(){ return _clientId; }
188-
AwsClientStatus status(){ return _status; }
189-
AsyncClient* client(){ return _client; }
187+
uint32_t id() const { return _clientId; }
188+
AwsClientStatus status() const { return _status; }
189+
AsyncClient* client() { return _client; }
190+
const AsyncClient* client() const { return _client; }
190191
AsyncWebSocket *server(){ return _server; }
192+
const AsyncWebSocket *server() const { return _server; }
191193
AwsFrameInfo const &pinfo() const { return _pinfo; }
192194

193-
IPAddress remoteIP();
194-
uint16_t remotePort();
195+
IPAddress remoteIP() const;
196+
uint16_t remotePort() const;
195197

196198
//control frames
197199
void close(uint16_t code=0, const char * message=NULL);
@@ -207,7 +209,7 @@ class AsyncWebSocketClient {
207209

208210
//data packets
209211
void message(AsyncWebSocketMessage *message){ _queueMessage(message); }
210-
bool queueIsFull();
212+
bool queueIsFull() const;
211213
size_t queueLen() { return _messageQueue.length() + _controlQueue.length(); }
212214

213215
size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3)));
@@ -247,7 +249,7 @@ typedef std::function<void(AsyncWebSocket * server, AsyncWebSocketClient * clien
247249
//WebServer Handler implementation that plays the role of a socket server
248250
class AsyncWebSocket: public AsyncWebHandler {
249251
public:
250-
typedef LinkedList<AsyncWebSocketClient *> AsyncWebSocketClientLinkedList;
252+
typedef std::list<AsyncWebSocketClient> AsyncWebSocketClientLinkedList;
251253
private:
252254
String _url;
253255
AsyncWebSocketClientLinkedList _clients;
@@ -329,7 +331,7 @@ class AsyncWebSocket: public AsyncWebHandler {
329331

330332
//system callbacks (do not call)
331333
uint32_t _getNextId(){ return _cNextId++; }
332-
void _addClient(AsyncWebSocketClient * client);
334+
AsyncWebSocketClient *_newClient(AsyncWebServerRequest *request);
333335
void _handleDisconnect(AsyncWebSocketClient * client);
334336
void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
335337
virtual bool canHandle(AsyncWebServerRequest *request) override final;
@@ -342,7 +344,7 @@ class AsyncWebSocket: public AsyncWebHandler {
342344
std::list<AsyncWebSocketMessageBuffer> _buffers;
343345
void _cleanBuffers();
344346

345-
AsyncWebSocketClientLinkedList getClients() const;
347+
const AsyncWebSocketClientLinkedList &getClients() const;
346348
};
347349

348350
//WebServer response to authenticate the socket and detach the tcp client from the web server request

0 commit comments

Comments
 (0)