Removed dumb self written reference counted smart pointer and replaced it with std::shared_ptr

This commit is contained in:
2020-12-20 04:53:18 +01:00
parent 9b98550f64
commit 84833546f0
2 changed files with 313 additions and 300 deletions

View File

@ -129,8 +129,8 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer()
:_data(nullptr) :_data(nullptr)
,_len(0) ,_len(0)
,_lock(false) // ,_lock(false)
,_count(0) // ,_count(0)
{ {
Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this)); Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this));
} }
@ -138,89 +138,82 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer()
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t size) AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t size)
:_data(nullptr) :_data(nullptr)
,_len(size) ,_len(size)
,_lock(false) // ,_lock(false)
,_count(0) // ,_count(0)
{ {
Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this)); Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this));
if (!data) { if (!data)
return; return;
}
_data = new uint8_t[_len + 1]; _data = std::make_unique<uint8_t[]>(_len + 1);
memcpy(_data.get(), data, _len);
if (_data) { _data[_len] = 0;
memcpy(_data, data, _len);
_data[_len] = 0;
}
} }
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size)
:_data(nullptr) :_data(nullptr)
,_len(size) ,_len(size)
,_lock(false) // ,_lock(false)
,_count(0) // ,_count(0)
{ {
Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this)); Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this));
_data = new uint8_t[_len + 1]; _data = std::make_unique<uint8_t[]>(_len + 1);
_data[_len] = 0;
if (_data) {
_data[_len] = 0;
}
} }
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer & copy) //AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer & copy)
:_data(nullptr) // :_data(nullptr)
,_len(0) // ,_len(0)
,_lock(false) // ,_lock(false)
,_count(0) // ,_count(0)
{ //{
Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this)); // Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this));
_len = copy._len; // _len = copy._len;
_lock = copy._lock; // _lock = copy._lock;
_count = 0; // _count = 0;
if (_len) { // if (_len) {
_data = new uint8_t[_len + 1]; // _data = new uint8_t[_len + 1];
_data[_len] = 0; // _data[_len] = 0;
} // }
if (_data) { // if (_data) {
memcpy(_data, copy._data, _len); // memcpy(_data, copy._data, _len);
_data[_len] = 0; // _data[_len] = 0;
} // }
} //}
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer && copy) //AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer && copy)
:_data(nullptr) // :_data(nullptr)
,_len(0) // ,_len(0)
,_lock(false) // ,_lock(false)
,_count(0) // ,_count(0)
{ //{
Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this)); // Serial.printf("AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() this=0x%llx\r\n", uint64_t(this));
_len = copy._len; // _len = copy._len;
_lock = copy._lock; // _lock = copy._lock;
_count = 0; // _count = 0;
if (copy._data) { // if (copy._data) {
_data = copy._data; // _data = copy._data;
copy._data = nullptr; // copy._data = nullptr;
} // }
} //}
AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer()
{ {
Serial.printf("AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() this=0x%llx data=0x%llx\r\n", uint64_t(this), uint64_t(_data)); Serial.printf("AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() this=0x%llx data=0x%llx size=0x%x\r\n", uint64_t(this), uint64_t(_data.get()), _len);
if (_data) { // if (_data) {
delete[] _data; // delete[] _data;
} // }
} }
bool AsyncWebSocketMessageBuffer::reserve(size_t size) bool AsyncWebSocketMessageBuffer::reserve(size_t size)
@ -229,20 +222,9 @@ bool AsyncWebSocketMessageBuffer::reserve(size_t size)
_len = size; _len = size;
if (_data) { _data = std::make_unique<uint8_t[]>(_len + 1);
delete[] _data; _data[_len] = 0;
_data = nullptr; return true;
}
_data = new uint8_t[_len + 1];
if (_data) {
_data[_len] = 0;
return true;
} else {
return false;
}
} }
@ -395,7 +377,7 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() {
*/ */
AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
:_len(0) :_len(0)
,_sent(0) ,_sent(0)
,_ack(0) ,_ack(0)
@ -407,7 +389,7 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff
if (buffer) { if (buffer) {
_WSbuffer = buffer; _WSbuffer = buffer;
(*_WSbuffer)++; //(*_WSbuffer)++;
_data = buffer->get(); _data = buffer->get();
_len = buffer->length(); _len = buffer->length();
_status = WS_MSG_SENDING; _status = WS_MSG_SENDING;
@ -420,9 +402,9 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff
AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() {
if (_WSbuffer) { // if (_WSbuffer) {
(*_WSbuffer)--; // decreases the counter. // (*_WSbuffer)--; // decreases the counter.
} // }
} }
void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) { void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) {
@ -654,7 +636,7 @@ void AsyncWebSocketClient::_queueMessage(const char *data, size_t len, uint8_t o
_runQueue(); _runQueue();
} }
void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) void AsyncWebSocketClient::_queueMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
{ {
Serial.printf("AsyncWebSocketClient::_queueMessage this=0x%llx task=0x%llx %s\r\n", uint64_t(this), uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle())); Serial.printf("AsyncWebSocketClient::_queueMessage this=0x%llx task=0x%llx %s\r\n", uint64_t(this), uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle()));
@ -904,50 +886,57 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data){
free(message); free(message);
} }
} }
void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) void AsyncWebSocketClient::text(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
{ {
_queueMessage(buffer); _queueMessage(buffer);
} }
void AsyncWebSocketClient::binary(const char * message, size_t len){ void AsyncWebSocketClient::binary(const char * message, size_t len)
_queueMessage(message, len, WS_BINARY);
}
void AsyncWebSocketClient::binary(const char * message){
binary(message, strlen(message));
}
void AsyncWebSocketClient::binary(uint8_t * message, size_t len){
binary((const char *)message, len);
}
void AsyncWebSocketClient::binary(char * message){
binary(message, strlen(message));
}
void AsyncWebSocketClient::binary(const String &message){
binary(message.c_str(), message.length());
}
void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len){
PGM_P p = reinterpret_cast<PGM_P>(data);
char * message = (char*) malloc(len);
if(message){
for(size_t b=0; b<len; b++)
message[b] = pgm_read_byte(p++);
binary(message, len);
free(message);
}
}
void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer)
{ {
_queueMessage(buffer, WS_BINARY); _queueMessage(message, len, WS_BINARY);
}
void AsyncWebSocketClient::binary(const char * message)
{
binary(message, strlen(message));
}
void AsyncWebSocketClient::binary(uint8_t * message, size_t len)
{
binary((const char *)message, len);
}
void AsyncWebSocketClient::binary(char * message)
{
binary(message, strlen(message));
}
void AsyncWebSocketClient::binary(const String &message)
{
binary(message.c_str(), message.length());
}
void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len)
{
PGM_P p = reinterpret_cast<PGM_P>(data);
char * message = (char*) malloc(len);
if(message) {
for(size_t b=0; b<len; b++)
message[b] = pgm_read_byte(p++);
binary(message, len);
free(message);
}
}
void AsyncWebSocketClient::binary(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
{
_queueMessage(buffer, WS_BINARY);
} }
IPAddress AsyncWebSocketClient::remoteIP() const { IPAddress AsyncWebSocketClient::remoteIP() const
if(!_client) { {
if (!_client) {
return IPAddress(0U); return IPAddress(0U);
} }
return _client->remoteIP(); return _client->remoteIP();
} }
uint16_t AsyncWebSocketClient::remotePort() const { uint16_t AsyncWebSocketClient::remotePort() const
{
if(!_client) { if(!_client) {
return 0; return 0;
} }
@ -1028,8 +1017,10 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){
c->close(code, message); c->close(code, message);
} }
void AsyncWebSocket::closeAll(uint16_t code, const char * message){ void AsyncWebSocket::closeAll(uint16_t code, const char * message)
for(auto &c: _clients){ {
for(auto &c: _clients)
{
if(c.status() == WS_CONNECTED) if(c.status() == WS_CONNECTED)
c.close(code, message); c.close(code, message);
} }
@ -1042,70 +1033,75 @@ void AsyncWebSocket::cleanupClients(uint16_t maxClients)
} }
} }
void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){ void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len)
{
AsyncWebSocketClient * c = client(id); AsyncWebSocketClient * c = client(id);
if(c) if(c)
c->ping(data, len); c->ping(data, len);
} }
void AsyncWebSocket::pingAll(uint8_t *data, size_t len){ void AsyncWebSocket::pingAll(uint8_t *data, size_t len)
{
for (auto &c : _clients){ for (auto &c : _clients){
if (c.status() == WS_CONNECTED) if (c.status() == WS_CONNECTED)
c.ping(data, len); c.ping(data, len);
} }
} }
void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){ void AsyncWebSocket::text(uint32_t id, const char * message, size_t len)
{
AsyncWebSocketClient *c = client(id); AsyncWebSocketClient *c = client(id);
if(c) if(c)
c->text(message, len); c->text(message, len);
} }
void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer *buffer) void AsyncWebSocket::textAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
{ {
if (!buffer) if (!buffer)
return; return;
buffer->lock(); //buffer->lock();
for(auto &c : _clients) for(auto &c : _clients)
if (c.status() == WS_CONNECTED) if (c.status() == WS_CONNECTED)
c.text(buffer); c.text(buffer);
buffer->unlock(); //buffer->unlock();
_cleanBuffers(); _cleanBuffers();
} }
void AsyncWebSocket::textAll(const char * message, size_t len){ void AsyncWebSocket::textAll(const char * message, size_t len)
AsyncWebSocketMessageBuffer * WSBuffer = makeBuffer((uint8_t *)message, len); {
std::shared_ptr<AsyncWebSocketMessageBuffer> WSBuffer = makeBuffer((uint8_t *)message, len);
textAll(WSBuffer); textAll(WSBuffer);
} }
void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len){ void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len)
AsyncWebSocketClient * c = client(id); {
if(c) AsyncWebSocketClient *c = client(id);
c->binary(message, len); if (c)
c->binary(message, len);
} }
void AsyncWebSocket::binaryAll(const char * message, size_t len){ void AsyncWebSocket::binaryAll(const char * message, size_t len){
AsyncWebSocketMessageBuffer * buffer = makeBuffer((uint8_t *)message, len); std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = makeBuffer((uint8_t *)message, len);
binaryAll(buffer); binaryAll(buffer);
} }
void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer *buffer) void AsyncWebSocket::binaryAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer)
{ {
if (!buffer) if (!buffer)
return; return;
buffer->lock(); //buffer->lock();
for (auto &c : _clients) for (auto &c : _clients)
if (c.status() == WS_CONNECTED) if (c.status() == WS_CONNECTED)
c.binary(buffer); c.binary(buffer);
buffer->unlock(); //buffer->unlock();
_cleanBuffers(); _cleanBuffers();
} }
@ -1117,18 +1113,19 @@ void AsyncWebSocket::message(uint32_t id, const char *data, size_t len, uint8_t
c->message(data, len, opcode, mask); c->message(data, len, opcode, mask);
} }
void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) void AsyncWebSocket::message(uint32_t id, std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
{ {
AsyncWebSocketClient *c = client(id); AsyncWebSocketClient *c = client(id);
if (c) if (c)
c->message(buffer, opcode, mask); c->message(buffer, opcode, mask);
} }
void AsyncWebSocket::messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask){ void AsyncWebSocket::messageAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode, bool mask)
for (auto &c : _clients){ {
for (auto &c : _clients)
if (c.status() == WS_CONNECTED) if (c.status() == WS_CONNECTED)
c.message(buffer, opcode, mask); c.message(buffer, opcode, mask);
}
_cleanBuffers(); _cleanBuffers();
} }
@ -1144,28 +1141,26 @@ size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){
return 0; return 0;
} }
size_t AsyncWebSocket::printfAll(const char *format, ...) { size_t AsyncWebSocket::printfAll(const char *format, ...)
va_list arg; {
char* temp = new char[MAX_PRINTF_LEN]; va_list arg;
if(!temp){ char* temp = new char[MAX_PRINTF_LEN];
return 0; if (!temp) {
} return 0;
va_start(arg, format); }
size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); va_start(arg, format);
va_end(arg); size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg);
delete[] temp; va_end(arg);
delete[] temp;
AsyncWebSocketMessageBuffer * buffer = makeBuffer(len);
if (!buffer) {
return 0;
}
va_start(arg, format); std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = makeBuffer(len);
vsnprintf( (char *)buffer->get(), len + 1, format, arg);
va_end(arg);
textAll(buffer); va_start(arg, format);
return len; vsnprintf( (char *)buffer->get(), len + 1, format, arg);
va_end(arg);
textAll(buffer);
return len;
} }
#ifndef ESP32 #ifndef ESP32
@ -1182,100 +1177,117 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){
} }
#endif #endif
size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...)
va_list arg; {
char* temp = new char[MAX_PRINTF_LEN]; va_list arg;
if(!temp){ char* temp = new char[MAX_PRINTF_LEN];
return 0; if (!temp) {
} return 0;
va_start(arg, formatP); }
size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); va_start(arg, formatP);
va_end(arg); size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg);
delete[] temp; va_end(arg);
delete[] temp;
AsyncWebSocketMessageBuffer * buffer = makeBuffer(len + 1);
if (!buffer) {
return 0;
}
va_start(arg, formatP); std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = makeBuffer(len + 1);
vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg);
va_end(arg);
textAll(buffer); va_start(arg, formatP);
return len; vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg);
va_end(arg);
textAll(buffer);
return len;
} }
void AsyncWebSocket::text(uint32_t id, const char * message){ void AsyncWebSocket::text(uint32_t id, const char * message)
text(id, message, strlen(message)); {
text(id, message, strlen(message));
} }
void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len){ void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len)
text(id, (const char *)message, len); {
text(id, (const char *)message, len);
} }
void AsyncWebSocket::text(uint32_t id, char * message){ void AsyncWebSocket::text(uint32_t id, char * message)
text(id, message, strlen(message)); {
text(id, message, strlen(message));
} }
void AsyncWebSocket::text(uint32_t id, const String &message){ void AsyncWebSocket::text(uint32_t id, const String &message)
text(id, message.c_str(), message.length()); {
text(id, message.c_str(), message.length());
} }
void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message){ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message)
AsyncWebSocketClient * c = client(id); {
if(c != NULL) AsyncWebSocketClient * c = client(id);
c->text(message); if(c != NULL)
c->text(message);
} }
void AsyncWebSocket::textAll(const char * message){ void AsyncWebSocket::textAll(const char * message)
textAll(message, strlen(message)); {
textAll(message, strlen(message));
} }
void AsyncWebSocket::textAll(uint8_t * message, size_t len){ void AsyncWebSocket::textAll(uint8_t * message, size_t len)
textAll((const char *)message, len); {
textAll((const char *)message, len);
} }
void AsyncWebSocket::textAll(char * message){ void AsyncWebSocket::textAll(char * message)
textAll(message, strlen(message)); {
textAll(message, strlen(message));
} }
void AsyncWebSocket::textAll(const String &message){ void AsyncWebSocket::textAll(const String &message)
textAll(message.c_str(), message.length()); {
textAll(message.c_str(), message.length());
} }
void AsyncWebSocket::textAll(const __FlashStringHelper *message){ void AsyncWebSocket::textAll(const __FlashStringHelper *message)
for(auto &c : _clients){ {
if(c.status() == WS_CONNECTED) for (auto &c : _clients)
c.text(message); if (c.status() == WS_CONNECTED)
} c.text(message);
} }
void AsyncWebSocket::binary(uint32_t id, const char * message){ void AsyncWebSocket::binary(uint32_t id, const char * message)
binary(id, message, strlen(message)); {
binary(id, message, strlen(message));
} }
void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len){ void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len)
binary(id, (const char *)message, len); {
binary(id, (const char *)message, len);
} }
void AsyncWebSocket::binary(uint32_t id, char * message){ void AsyncWebSocket::binary(uint32_t id, char * message)
binary(id, message, strlen(message)); {
binary(id, message, strlen(message));
} }
void AsyncWebSocket::binary(uint32_t id, const String &message){ void AsyncWebSocket::binary(uint32_t id, const String &message)
binary(id, message.c_str(), message.length()); {
binary(id, message.c_str(), message.length());
} }
void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len){ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len)
AsyncWebSocketClient * c = client(id); {
if(c != NULL) AsyncWebSocketClient * c = client(id);
c-> binary(message, len); if (c != NULL)
c-> binary(message, len);
} }
void AsyncWebSocket::binaryAll(const char * message){ void AsyncWebSocket::binaryAll(const char * message)
binaryAll(message, strlen(message)); {
binaryAll(message, strlen(message));
} }
void AsyncWebSocket::binaryAll(uint8_t * message, size_t len){ void AsyncWebSocket::binaryAll(uint8_t * message, size_t len)
binaryAll((const char *)message, len); {
binaryAll((const char *)message, len);
} }
void AsyncWebSocket::binaryAll(char * message){ void AsyncWebSocket::binaryAll(char * message)
binaryAll(message, strlen(message)); {
binaryAll(message, strlen(message));
} }
void AsyncWebSocket::binaryAll(const String &message){ void AsyncWebSocket::binaryAll(const String &message)
binaryAll(message.c_str(), message.length()); {
binaryAll(message.c_str(), message.length());
}
void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len)
{
for (auto &c : _clients) {
if (c.status() == WS_CONNECTED)
c.binary(message, len);
}
} }
void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){
for(auto &c : _clients) {
if(c.status() == WS_CONNECTED)
c.binary(message, len);
}
}
const char * WS_STR_CONNECTION = "Connection"; const char * WS_STR_CONNECTION = "Connection";
const char * WS_STR_UPGRADE = "Upgrade"; const char * WS_STR_UPGRADE = "Upgrade";
@ -1286,72 +1298,72 @@ const char * WS_STR_PROTOCOL = "Sec-WebSocket-Protocol";
const char * WS_STR_ACCEPT = "Sec-WebSocket-Accept"; const char * WS_STR_ACCEPT = "Sec-WebSocket-Accept";
const char * WS_STR_UUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const char * WS_STR_UUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request){ bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request)
if(!_enabled) {
return false; if(!_enabled)
return false;
if(request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS))
return false;
request->addInterestingHeader(WS_STR_CONNECTION); if(request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS))
request->addInterestingHeader(WS_STR_UPGRADE); return false;
request->addInterestingHeader(WS_STR_ORIGIN);
request->addInterestingHeader(WS_STR_VERSION); request->addInterestingHeader(WS_STR_CONNECTION);
request->addInterestingHeader(WS_STR_KEY); request->addInterestingHeader(WS_STR_UPGRADE);
request->addInterestingHeader(WS_STR_PROTOCOL); request->addInterestingHeader(WS_STR_ORIGIN);
return true; request->addInterestingHeader(WS_STR_VERSION);
request->addInterestingHeader(WS_STR_KEY);
request->addInterestingHeader(WS_STR_PROTOCOL);
return true;
} }
void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request)
if(!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){ {
request->send(400); if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){
return; request->send(400);
} return;
if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())){ }
return request->requestAuthentication(); if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())){
} return request->requestAuthentication();
AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); }
if(version->value().toInt() != 13){ AsyncWebHeader* version = request->getHeader(WS_STR_VERSION);
AsyncWebServerResponse *response = request->beginResponse(400); if (version->value().toInt() != 13){
response->addHeader(WS_STR_VERSION,"13"); AsyncWebServerResponse *response = request->beginResponse(400);
response->addHeader(WS_STR_VERSION,"13");
request->send(response);
return;
}
AsyncWebHeader* key = request->getHeader(WS_STR_KEY);
AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this);
if (request->hasHeader(WS_STR_PROTOCOL)){
AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL);
//ToDo: check protocol
response->addHeader(WS_STR_PROTOCOL, protocol->value());
}
request->send(response); request->send(response);
return;
}
AsyncWebHeader* key = request->getHeader(WS_STR_KEY);
AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this);
if(request->hasHeader(WS_STR_PROTOCOL)){
AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL);
//ToDo: check protocol
response->addHeader(WS_STR_PROTOCOL, protocol->value());
}
request->send(response);
} }
AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(size_t size) std::shared_ptr<AsyncWebSocketMessageBuffer> AsyncWebSocket::makeBuffer(size_t size)
{ {
Serial.printf("AsyncWebSocket::makeBuffer task=0x%llx %s\r\n", uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle())); Serial.printf("AsyncWebSocket::makeBuffer task=0x%llx %s\r\n", uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle()));
AsyncWebSocketMessageBuffer *buffer{}; std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = std::make_shared<AsyncWebSocketMessageBuffer>(size);
{ {
AsyncWebLockGuard l(_lock, "AsyncWebSocket::makeBuffer"); AsyncWebLockGuard l(_lock, "AsyncWebSocket::makeBuffer");
_buffers.emplace_back(size); _buffers.emplace_back(buffer);
buffer = &_buffers.back();
} }
return buffer; return buffer;
} }
AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) std::shared_ptr<AsyncWebSocketMessageBuffer> AsyncWebSocket::makeBuffer(uint8_t * data, size_t size)
{ {
Serial.printf("AsyncWebSocket::makeBuffer task=0x%llx %s\r\n", uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle())); Serial.printf("AsyncWebSocket::makeBuffer task=0x%llx %s\r\n", uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle()));
AsyncWebSocketMessageBuffer *buffer{}; std::shared_ptr<AsyncWebSocketMessageBuffer> buffer = std::make_shared<AsyncWebSocketMessageBuffer>(data, size);
{ {
AsyncWebLockGuard l(_lock, "AsyncWebSocket::makeBuffer"); AsyncWebLockGuard l(_lock, "AsyncWebSocket::makeBuffer");
_buffers.emplace_back(data, size); _buffers.emplace_back(buffer);
buffer = &_buffers.back();
} }
return buffer; return buffer;
@ -1362,13 +1374,12 @@ void AsyncWebSocket::_cleanBuffers()
Serial.printf("AsyncWebSocket::_cleanBuffers task=0x%llx %s\r\n", uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle())); Serial.printf("AsyncWebSocket::_cleanBuffers task=0x%llx %s\r\n", uint64_t(xTaskGetCurrentTaskHandle()), pcTaskGetTaskName(xTaskGetCurrentTaskHandle()));
AsyncWebLockGuard l(_lock, "AsyncWebSocket::_cleanBuffers()"); AsyncWebLockGuard l(_lock, "AsyncWebSocket::_cleanBuffers()");
for (auto iter = std::begin(_buffers); iter != std::end(_buffers);) for (auto iter = std::begin(_buffers); iter != std::end(_buffers);)
{ {
if(iter->canDelete()) if (iter->lock())
iter = _buffers.erase(iter);
else
iter++; iter++;
else
iter = _buffers.erase(iter);
} }
} }

View File

@ -35,6 +35,7 @@
#include <list> #include <list>
#include <queue> #include <queue>
#include <memory>
#ifdef ESP8266 #ifdef ESP8266
#include <Hash.h> #include <Hash.h>
@ -85,29 +86,30 @@ typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_
class AsyncWebSocketMessageBuffer { class AsyncWebSocketMessageBuffer {
private: private:
uint8_t * _data; std::unique_ptr<uint8_t[]> _data;
size_t _len; //uint8_t * _data;
bool _lock; size_t _len{};
uint32_t _count; //bool _lock;
//uint32_t _count;
public: public:
AsyncWebSocketMessageBuffer(); AsyncWebSocketMessageBuffer();
AsyncWebSocketMessageBuffer(size_t size); AsyncWebSocketMessageBuffer(size_t size);
AsyncWebSocketMessageBuffer(uint8_t * data, size_t size); AsyncWebSocketMessageBuffer(uint8_t *data, size_t size);
AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); //AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &);
AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); //AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&);
~AsyncWebSocketMessageBuffer(); ~AsyncWebSocketMessageBuffer();
void operator ++(int i) { Serial.printf("AsyncWebSocketMessageBuffer::operator++() this=0x%llx\r\n", uint64_t(this)); (void)i; _count++; } //void operator ++(int i) { Serial.printf("AsyncWebSocketMessageBuffer::operator++() this=0x%llx\r\n", uint64_t(this)); (void)i; _count++; }
void operator --(int i) { Serial.printf("AsyncWebSocketMessageBuffer::operator--() this=0x%llx\r\n", uint64_t(this)); (void)i; if (_count > 0) { _count--; } ; } //void operator --(int i) { Serial.printf("AsyncWebSocketMessageBuffer::operator--() this=0x%llx\r\n", uint64_t(this)); (void)i; if (_count > 0) { _count--; } ; }
bool reserve(size_t size); bool reserve(size_t size);
void lock() { Serial.printf("AsyncWebSocketMessageBuffer::lock() this=0x%llx\r\n", uint64_t(this)); _lock = true; } //void lock() { Serial.printf("AsyncWebSocketMessageBuffer::lock() this=0x%llx\r\n", uint64_t(this)); _lock = true; }
void unlock() { Serial.printf("AsyncWebSocketMessageBuffer::unlock() this=0x%llx\r\n", uint64_t(this)); _lock = false; } //void unlock() { Serial.printf("AsyncWebSocketMessageBuffer::unlock() this=0x%llx\r\n", uint64_t(this)); _lock = false; }
uint8_t *get() { Serial.printf("AsyncWebSocketMessageBuffer::get() this=0x%llx\r\n", uint64_t(this)); return _data; } uint8_t *get() { Serial.printf("AsyncWebSocketMessageBuffer::get() this=0x%llx\r\n", uint64_t(this)); return _data.get(); }
size_t length() { Serial.printf("AsyncWebSocketMessageBuffer::length() this=0x%llx\r\n", uint64_t(this)); return _len; } size_t length() { Serial.printf("AsyncWebSocketMessageBuffer::length() this=0x%llx\r\n", uint64_t(this)); return _len; }
uint32_t count() { Serial.printf("AsyncWebSocketMessageBuffer::count() this=0x%llx\r\n", uint64_t(this)); return _count; } //uint32_t count() { Serial.printf("AsyncWebSocketMessageBuffer::count() this=0x%llx\r\n", uint64_t(this)); return _count; }
bool canDelete() { Serial.printf("AsyncWebSocketMessageBuffer::canDelete() this=0x%llx\r\n", uint64_t(this)); return (!_count && !_lock); } //bool canDelete() { Serial.printf("AsyncWebSocketMessageBuffer::canDelete() this=0x%llx\r\n", uint64_t(this)); return (!_count && !_lock); }
friend AsyncWebSocket; //friend AsyncWebSocket;
}; };
@ -148,10 +150,10 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage {
size_t _sent; size_t _sent;
size_t _ack; size_t _ack;
size_t _acked; size_t _acked;
AsyncWebSocketMessageBuffer *_WSbuffer; std::shared_ptr<AsyncWebSocketMessageBuffer> _WSbuffer;
public: public:
AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); AsyncWebSocketMultiMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
virtual ~AsyncWebSocketMultiMessage() override; virtual ~AsyncWebSocketMultiMessage() override;
virtual bool betweenFrames() const override { return _acked == _ack; } virtual bool betweenFrames() const override { return _acked == _ack; }
virtual void ack(size_t len, uint32_t time) override ; virtual void ack(size_t len, uint32_t time) override ;
@ -179,7 +181,7 @@ public:
new (&basicMessage) AsyncWebSocketBasicMessage{data, len, opcode, mask}; new (&basicMessage) AsyncWebSocketBasicMessage{data, len, opcode, mask};
} }
PolymorphMessageContainer(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) : PolymorphMessageContainer(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false) :
type{Type::Multi} type{Type::Multi}
{ {
new (&multiMessage) AsyncWebSocketMultiMessage{buffer, opcode, mask}; new (&multiMessage) AsyncWebSocketMultiMessage{buffer, opcode, mask};
@ -235,7 +237,7 @@ class AsyncWebSocketClient {
void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false); void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false);
void _queueMessage(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); void _queueMessage(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false);
void _queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); void _queueMessage(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
void _runQueue(); void _runQueue();
public: public:
@ -270,7 +272,7 @@ class AsyncWebSocketClient {
//data packets //data packets
void message(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(data, len, opcode, mask); } void message(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(data, len, opcode, mask); }
void message(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } void message(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); }
bool queueIsFull() const; bool queueIsFull() const;
size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3))); size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3)));
@ -283,7 +285,7 @@ class AsyncWebSocketClient {
void text(char * message); void text(char * message);
void text(const String &message); void text(const String &message);
void text(const __FlashStringHelper *data); void text(const __FlashStringHelper *data);
void text(AsyncWebSocketMessageBuffer *buffer); void text(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
void binary(const char * message, size_t len); void binary(const char * message, size_t len);
void binary(const char * message); void binary(const char * message);
@ -291,7 +293,7 @@ class AsyncWebSocketClient {
void binary(char * message); void binary(char * message);
void binary(const String &message); void binary(const String &message);
void binary(const __FlashStringHelper *data, size_t len); void binary(const __FlashStringHelper *data, size_t len);
void binary(AsyncWebSocketMessageBuffer *buffer); void binary(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
bool canSend() const; bool canSend() const;
@ -349,7 +351,7 @@ class AsyncWebSocket: public AsyncWebHandler {
void textAll(char * message); void textAll(char * message);
void textAll(const String &message); void textAll(const String &message);
void textAll(const __FlashStringHelper *message); // need to convert void textAll(const __FlashStringHelper *message); // need to convert
void textAll(AsyncWebSocketMessageBuffer *buffer); void textAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
void binary(uint32_t id, const char * message, size_t len); void binary(uint32_t id, const char * message, size_t len);
void binary(uint32_t id, const char * message); void binary(uint32_t id, const char * message);
@ -364,11 +366,11 @@ class AsyncWebSocket: public AsyncWebHandler {
void binaryAll(char * message); void binaryAll(char * message);
void binaryAll(const String &message); void binaryAll(const String &message);
void binaryAll(const __FlashStringHelper *message, size_t len); void binaryAll(const __FlashStringHelper *message, size_t len);
void binaryAll(AsyncWebSocketMessageBuffer *buffer); void binaryAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer);
void message(uint32_t id, const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); void message(uint32_t id, const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false);
void message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); void message(uint32_t id, std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
void messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); void messageAll(std::shared_ptr<AsyncWebSocketMessageBuffer> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3)));
@ -393,9 +395,9 @@ class AsyncWebSocket: public AsyncWebHandler {
// messagebuffer functions/objects. // messagebuffer functions/objects.
AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); std::shared_ptr<AsyncWebSocketMessageBuffer> makeBuffer(size_t size = 0);
AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); std::shared_ptr<AsyncWebSocketMessageBuffer> makeBuffer(uint8_t * data, size_t size);
std::list<AsyncWebSocketMessageBuffer> _buffers; std::list<std::weak_ptr<AsyncWebSocketMessageBuffer>> _buffers;
void _cleanBuffers(); void _cleanBuffers();
const auto &getClients() const { return _clients; } const auto &getClients() const { return _clients; }