mirror of
https://github.com/me-no-dev/ESPAsyncWebServer.git
synced 2025-09-28 07:11:01 +02:00
Replace use of LinkedList<T> with std::list for AsyncWebServer clients
Fraction of commit 8bb1c704cd70dd58b318b296154a5404a1bd27d0 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.
This commit is contained in:
@@ -540,7 +540,6 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async
|
||||
_client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this);
|
||||
_client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this);
|
||||
_client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this);
|
||||
_server->_addClient(this);
|
||||
_server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0);
|
||||
delete request;
|
||||
memset(&_pinfo,0,sizeof(_pinfo));
|
||||
@@ -614,9 +613,8 @@ void AsyncWebSocketClient::_runQueue(){
|
||||
_clearQueue();
|
||||
}
|
||||
|
||||
bool AsyncWebSocketClient::queueIsFull(){
|
||||
if((_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED) ) return true;
|
||||
return false;
|
||||
bool AsyncWebSocketClient::queueIsFull() const {
|
||||
return (_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED);
|
||||
}
|
||||
|
||||
void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){
|
||||
@@ -909,14 +907,14 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer)
|
||||
_queueMessage(new AsyncWebSocketMultiMessage(buffer, WS_BINARY));
|
||||
}
|
||||
|
||||
IPAddress AsyncWebSocketClient::remoteIP() {
|
||||
IPAddress AsyncWebSocketClient::remoteIP() const {
|
||||
if(!_client) {
|
||||
return IPAddress(0U);
|
||||
}
|
||||
return _client->remoteIP();
|
||||
}
|
||||
|
||||
uint16_t AsyncWebSocketClient::remotePort() {
|
||||
uint16_t AsyncWebSocketClient::remotePort() const {
|
||||
if(!_client) {
|
||||
return 0;
|
||||
}
|
||||
@@ -931,7 +929,6 @@ uint16_t AsyncWebSocketClient::remotePort() {
|
||||
|
||||
AsyncWebSocket::AsyncWebSocket(const String& url)
|
||||
:_url(url)
|
||||
,_clients(LinkedList<AsyncWebSocketClient *>([](AsyncWebSocketClient *c){ delete c; }))
|
||||
,_cNextId(1)
|
||||
,_enabled(true)
|
||||
{
|
||||
@@ -946,44 +943,45 @@ void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType ty
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocket::_addClient(AsyncWebSocketClient * client){
|
||||
_clients.add(client);
|
||||
AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request)
|
||||
{
|
||||
_clients.emplace_back(request, this);
|
||||
return &_clients.back();
|
||||
}
|
||||
|
||||
void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient * client){
|
||||
|
||||
_clients.remove_first([=](AsyncWebSocketClient * c){
|
||||
return c->id() == client->id();
|
||||
});
|
||||
const auto client_id = client->id();
|
||||
const auto iter = std::find_if(std::begin(_clients), std::end(_clients),
|
||||
[client_id](const AsyncWebSocketClient &c){ return c.id() == client_id; });
|
||||
if (iter != std::end(_clients))
|
||||
_clients.erase(iter);
|
||||
}
|
||||
|
||||
bool AsyncWebSocket::availableForWriteAll(){
|
||||
for(const auto& c: _clients){
|
||||
if(c->queueIsFull()) return false;
|
||||
}
|
||||
return true;
|
||||
return std::none_of(std::begin(_clients), std::end(_clients),
|
||||
[](const AsyncWebSocketClient &c){ return c.queueIsFull(); });
|
||||
}
|
||||
|
||||
bool AsyncWebSocket::availableForWrite(uint32_t id){
|
||||
for(const auto& c: _clients){
|
||||
if(c->queueIsFull() && (c->id() == id )) return false;
|
||||
}
|
||||
return true;
|
||||
const auto iter = std::find_if(std::begin(_clients), std::end(_clients),
|
||||
[id](const AsyncWebSocketClient &c){ return c.id() == id; });
|
||||
if (iter == std::end(_clients))
|
||||
return true; // don't know why me-no-dev decided like this?
|
||||
return !iter->queueIsFull();
|
||||
}
|
||||
|
||||
size_t AsyncWebSocket::count() const {
|
||||
return _clients.count_if([](AsyncWebSocketClient * c){
|
||||
return c->status() == WS_CONNECTED;
|
||||
});
|
||||
return std::count_if(std::begin(_clients), std::end(_clients),
|
||||
[](const AsyncWebSocketClient &c){ return c.status() == WS_CONNECTED; });
|
||||
}
|
||||
|
||||
AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id){
|
||||
for(const auto &c: _clients){
|
||||
if(c->id() == id && c->status() == WS_CONNECTED){
|
||||
return c;
|
||||
}
|
||||
}
|
||||
const auto iter = std::find_if(std::begin(_clients), std::end(_clients),
|
||||
[id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; });
|
||||
if (iter == std::end(_clients))
|
||||
return nullptr;
|
||||
|
||||
return &(*iter);
|
||||
}
|
||||
|
||||
|
||||
@@ -994,16 +992,16 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){
|
||||
}
|
||||
|
||||
void AsyncWebSocket::closeAll(uint16_t code, const char * message){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->close(code, message);
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.close(code, message);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncWebSocket::cleanupClients(uint16_t maxClients)
|
||||
{
|
||||
if (count() > maxClients){
|
||||
_clients.front()->close();
|
||||
_clients.front().close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1014,9 +1012,9 @@ void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){
|
||||
}
|
||||
|
||||
void AsyncWebSocket::pingAll(uint8_t *data, size_t len){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->ping(data, len);
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.ping(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,9 +1027,9 @@ void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){
|
||||
void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer){
|
||||
if (!buffer) return;
|
||||
buffer->lock();
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED){
|
||||
c->text(buffer);
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED){
|
||||
c.text(buffer);
|
||||
}
|
||||
}
|
||||
buffer->unlock();
|
||||
@@ -1060,9 +1058,9 @@ void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer)
|
||||
{
|
||||
if (!buffer) return;
|
||||
buffer->lock();
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->binary(buffer);
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.binary(buffer);
|
||||
}
|
||||
buffer->unlock();
|
||||
_cleanBuffers();
|
||||
@@ -1075,9 +1073,9 @@ void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessage *message){
|
||||
}
|
||||
|
||||
void AsyncWebSocket::messageAll(AsyncWebSocketMultiMessage *message){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->message(message);
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.message(message);
|
||||
}
|
||||
_cleanBuffers();
|
||||
}
|
||||
@@ -1186,9 +1184,9 @@ void AsyncWebSocket::textAll(const String &message){
|
||||
textAll(message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::textAll(const __FlashStringHelper *message){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c->text(message);
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.text(message);
|
||||
}
|
||||
}
|
||||
void AsyncWebSocket::binary(uint32_t id, const char * message){
|
||||
@@ -1221,9 +1219,9 @@ void AsyncWebSocket::binaryAll(const String &message){
|
||||
binaryAll(message.c_str(), message.length());
|
||||
}
|
||||
void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){
|
||||
for(const auto& c: _clients){
|
||||
if(c->status() == WS_CONNECTED)
|
||||
c-> binary(message, len);
|
||||
for(auto& c: _clients){
|
||||
if(c.status() == WS_CONNECTED)
|
||||
c.binary(message, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1333,7 +1331,7 @@ void AsyncWebSocket::_cleanBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
AsyncWebSocket::AsyncWebSocketClientLinkedList AsyncWebSocket::getClients() const {
|
||||
const AsyncWebSocket::AsyncWebSocketClientLinkedList &AsyncWebSocket::getClients() const {
|
||||
return _clients;
|
||||
}
|
||||
|
||||
@@ -1391,7 +1389,7 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request){
|
||||
size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){
|
||||
(void)time;
|
||||
if(len){
|
||||
new AsyncWebSocketClient(request, _server);
|
||||
_server->_newClient(request);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -184,14 +184,16 @@ class AsyncWebSocketClient {
|
||||
~AsyncWebSocketClient();
|
||||
|
||||
//client id increments for the given server
|
||||
uint32_t id(){ return _clientId; }
|
||||
AwsClientStatus status(){ return _status; }
|
||||
uint32_t id() const { return _clientId; }
|
||||
AwsClientStatus status() const { return _status; }
|
||||
AsyncClient* client() { return _client; }
|
||||
const AsyncClient* client() const { return _client; }
|
||||
AsyncWebSocket *server(){ return _server; }
|
||||
const AsyncWebSocket *server() const { return _server; }
|
||||
AwsFrameInfo const &pinfo() const { return _pinfo; }
|
||||
|
||||
IPAddress remoteIP();
|
||||
uint16_t remotePort();
|
||||
IPAddress remoteIP() const;
|
||||
uint16_t remotePort() const;
|
||||
|
||||
//control frames
|
||||
void close(uint16_t code=0, const char * message=NULL);
|
||||
@@ -207,7 +209,7 @@ class AsyncWebSocketClient {
|
||||
|
||||
//data packets
|
||||
void message(AsyncWebSocketMessage *message){ _queueMessage(message); }
|
||||
bool queueIsFull();
|
||||
bool queueIsFull() const;
|
||||
size_t queueLen() { return _messageQueue.length() + _controlQueue.length(); }
|
||||
|
||||
size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
@@ -247,7 +249,7 @@ typedef std::function<void(AsyncWebSocket * server, AsyncWebSocketClient * clien
|
||||
//WebServer Handler implementation that plays the role of a socket server
|
||||
class AsyncWebSocket: public AsyncWebHandler {
|
||||
public:
|
||||
typedef LinkedList<AsyncWebSocketClient *> AsyncWebSocketClientLinkedList;
|
||||
typedef std::list<AsyncWebSocketClient> AsyncWebSocketClientLinkedList;
|
||||
private:
|
||||
String _url;
|
||||
AsyncWebSocketClientLinkedList _clients;
|
||||
@@ -329,7 +331,7 @@ class AsyncWebSocket: public AsyncWebHandler {
|
||||
|
||||
//system callbacks (do not call)
|
||||
uint32_t _getNextId(){ return _cNextId++; }
|
||||
void _addClient(AsyncWebSocketClient * client);
|
||||
AsyncWebSocketClient *_newClient(AsyncWebServerRequest *request);
|
||||
void _handleDisconnect(AsyncWebSocketClient * client);
|
||||
void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final;
|
||||
@@ -342,7 +344,7 @@ class AsyncWebSocket: public AsyncWebHandler {
|
||||
std::list<AsyncWebSocketMessageBuffer> _buffers;
|
||||
void _cleanBuffers();
|
||||
|
||||
AsyncWebSocketClientLinkedList getClients() const;
|
||||
const AsyncWebSocketClientLinkedList &getClients() const;
|
||||
};
|
||||
|
||||
//WebServer response to authenticate the socket and detach the tcp client from the web server request
|
||||
|
Reference in New Issue
Block a user