websocket code cleanup

add explicit constructors
remove exra calls, etc...
This commit is contained in:
Emil Muratov
2024-06-09 16:06:13 +09:00
committed by Mathieu Carbou
parent 4accf5cd1d
commit cceac170c9
2 changed files with 76 additions and 79 deletions

View File

@@ -132,17 +132,11 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool
* AsyncWebSocketMessageBuffer
*/
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer()
: _buffer(std::make_shared<std::vector<uint8_t>>(0))
{
}
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t* data, size_t size)
AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const uint8_t* data, size_t size)
: _buffer(std::make_shared<std::vector<uint8_t>>(size))
{
if (_buffer->capacity() < size) {
_buffer.reset();
_buffer = std::make_shared<std::vector<uint8_t>>(0);
_buffer->reserve(size);
} else {
std::memcpy(_buffer->data(), data, size);
}
@@ -152,16 +146,10 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size)
: _buffer(std::make_shared<std::vector<uint8_t>>(size))
{
if (_buffer->capacity() < size) {
_buffer.reset();
_buffer = std::make_shared<std::vector<uint8_t>>(0);
_buffer->reserve(size);
}
}
AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer()
{
_buffer.reset();
}
bool AsyncWebSocketMessageBuffer::reserve(size_t size)
{
if (_buffer->capacity() >= size)
@@ -228,7 +216,7 @@ public:
*/
AsyncWebSocketMessage::AsyncWebSocketMessage(std::shared_ptr<std::vector<uint8_t>> buffer, uint8_t opcode, bool mask) :
AsyncWebSocketMessage::AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) :
_WSbuffer{buffer},
_opcode(opcode & 0x07),
_mask{mask},
@@ -449,7 +437,7 @@ void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, si
_runQueue();
}
void AsyncWebSocketClient::_queueMessage(std::shared_ptr<std::vector<uint8_t>> buffer, uint8_t opcode, bool mask)
void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask)
{
if(_status != WS_CONNECTED)
return;
@@ -707,7 +695,7 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...)
#endif
namespace {
std::shared_ptr<std::vector<uint8_t>> makeSharedBuffer(const uint8_t *message, size_t len)
AsyncWebSocketSharedBuffer makeSharedBuffer(const uint8_t *message, size_t len)
{
auto buffer = std::make_shared<std::vector<uint8_t>>(len);
std::memcpy(buffer->data(), message, len);
@@ -723,7 +711,7 @@ void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer)
}
}
void AsyncWebSocketClient::text(std::shared_ptr<std::vector<uint8_t>> buffer)
void AsyncWebSocketClient::text(AsyncWebSocketSharedBuffer buffer)
{
_queueMessage(buffer);
}
@@ -748,6 +736,7 @@ void AsyncWebSocketClient::text(const String &message)
text(message.c_str(), message.length());
}
#ifndef ESP32
void AsyncWebSocketClient::text(const __FlashStringHelper *data)
{
PGM_P p = reinterpret_cast<PGM_P>(data);
@@ -768,6 +757,7 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data)
free(message);
}
}
#endif // ESP32
void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer)
{
@@ -777,7 +767,7 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer)
}
}
void AsyncWebSocketClient::binary(std::shared_ptr<std::vector<uint8_t>> buffer)
void AsyncWebSocketClient::binary(AsyncWebSocketSharedBuffer buffer)
{
_queueMessage(buffer, WS_BINARY);
}
@@ -802,6 +792,7 @@ void AsyncWebSocketClient::binary(const String &message)
binary(message.c_str(), message.length());
}
#ifndef ESP32
void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len)
{
PGM_P p = reinterpret_cast<PGM_P>(data);
@@ -812,7 +803,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len)
free(message);
}
}
#endif
IPAddress AsyncWebSocketClient::remoteIP() const
{
if (!_client)
@@ -835,16 +826,6 @@ uint16_t AsyncWebSocketClient::remotePort() const
* Async Web Socket - Each separate socket location
*/
AsyncWebSocket::AsyncWebSocket(const String& url)
:_url(url)
,_cNextId(1)
,_enabled(true)
{
_eventHandler = NULL;
}
AsyncWebSocket::~AsyncWebSocket(){}
void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
if(_eventHandler != NULL){
_eventHandler(this, client, type, arg, data, len);
@@ -880,7 +861,7 @@ size_t AsyncWebSocket::count() const
AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id)
{
const auto iter = std::find_if(std::begin(_clients), std::end(_clients),
const auto iter = std::find_if(_clients.begin(), _clients.end(),
[id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; });
if (iter == std::end(_clients))
return nullptr;
@@ -946,6 +927,7 @@ void AsyncWebSocket::text(uint32_t id, const String &message)
{
text(id, message.c_str(), message.length());
}
#ifndef ESP32
void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data)
{
PGM_P p = reinterpret_cast<PGM_P>(data);
@@ -967,6 +949,7 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data)
free(message);
}
}
#endif // ESP32
void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer *buffer)
{
if (buffer) {
@@ -974,7 +957,7 @@ void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer *buffer)
delete buffer;
}
}
void AsyncWebSocket::text(uint32_t id, std::shared_ptr<std::vector<uint8_t>> buffer)
void AsyncWebSocket::text(uint32_t id, AsyncWebSocketSharedBuffer buffer)
{
if (AsyncWebSocketClient *c = client(id))
c->text(buffer);
@@ -996,6 +979,7 @@ void AsyncWebSocket::textAll(const String &message)
{
textAll(message.c_str(), message.length());
}
#ifndef ESP32
void AsyncWebSocket::textAll(const __FlashStringHelper *data)
{
PGM_P p = reinterpret_cast<PGM_P>(data);
@@ -1016,6 +1000,7 @@ void AsyncWebSocket::textAll(const __FlashStringHelper *data)
free(message);
}
}
#endif // ESP32
void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer)
{
if (buffer) {
@@ -1024,7 +1009,7 @@ void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer)
}
}
void AsyncWebSocket::textAll(std::shared_ptr<std::vector<uint8_t>> buffer)
void AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer)
{
for (auto &c : _clients)
if (c.status() == WS_CONNECTED)
@@ -1048,6 +1033,7 @@ void AsyncWebSocket::binary(uint32_t id, const String &message)
{
binary(id, message.c_str(), message.length());
}
#ifndef ESP32
void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t len)
{
PGM_P p = reinterpret_cast<PGM_P>(data);
@@ -1059,6 +1045,7 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t
free(message);
}
}
#endif // ESP32
void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer)
{
if (buffer) {
@@ -1066,7 +1053,7 @@ void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer)
delete buffer;
}
}
void AsyncWebSocket::binary(uint32_t id, std::shared_ptr<std::vector<uint8_t>> buffer)
void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketSharedBuffer buffer)
{
if (AsyncWebSocketClient *c = client(id))
c->binary(buffer);
@@ -1089,6 +1076,7 @@ void AsyncWebSocket::binaryAll(const String &message)
{
binaryAll(message.c_str(), message.length());
}
#ifndef ESP32
void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len)
{
PGM_P p = reinterpret_cast<PGM_P>(data);
@@ -1100,6 +1088,7 @@ void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len)
free(message);
}
}
#endif // ESP32
void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer)
{
if (buffer) {
@@ -1107,7 +1096,7 @@ void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer)
delete buffer;
}
}
void AsyncWebSocket::binaryAll(std::shared_ptr<std::vector<uint8_t>> buffer)
void AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer)
{
for (auto &c : _clients)
if (c.status() == WS_CONNECTED)
@@ -1139,7 +1128,7 @@ size_t AsyncWebSocket::printfAll(const char *format, ...)
va_end(arg);
delete[] temp;
std::shared_ptr<std::vector<uint8_t>> buffer = std::make_shared<std::vector<uint8_t>>(len);
AsyncWebSocketSharedBuffer buffer = std::make_shared<std::vector<uint8_t>>(len);
va_start(arg, format);
vsnprintf( (char *)buffer->data(), len + 1, format, arg);
@@ -1175,7 +1164,7 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...)
va_end(arg);
delete[] temp;
std::shared_ptr<std::vector<uint8_t>> buffer = std::make_shared<std::vector<uint8_t>>(len + 1);
AsyncWebSocketSharedBuffer buffer = std::make_shared<std::vector<uint8_t>>(len + 1);
va_start(arg, formatP);
vsnprintf_P((char *)buffer->data(), len + 1, formatP, arg);
@@ -1195,6 +1184,8 @@ const char __WS_STR_PROTOCOL[] PROGMEM = { "Sec-WebSocket-Protocol" };
const char __WS_STR_ACCEPT[] PROGMEM = { "Sec-WebSocket-Accept" };
const char __WS_STR_UUID[] PROGMEM = { "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" };
#define WS_STR_UUID_LEN 36
#define WS_STR_CONNECTION FPSTR(__WS_STR_CONNECTION)
#define WS_STR_UPGRADE FPSTR(__WS_STR_UPGRADE)
#define WS_STR_ORIGIN FPSTR(__WS_STR_ORIGIN)
@@ -1270,7 +1261,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size)
}
}
AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t size)
AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(const uint8_t * data, size_t size)
{
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size);
if (buffer->length() != size)
@@ -1293,23 +1284,16 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket
_code = 101;
_sendContentLength = false;
uint8_t * hash = (uint8_t*)malloc(20);
if(hash == NULL)
{
_state = RESPONSE_FAILED;
return;
}
char * buffer = (char *) malloc(33);
if(buffer == NULL)
{
free(hash);
_state = RESPONSE_FAILED;
return;
}
uint8_t hash[20];
char buffer[33];
#ifdef ESP8266
sha1(key + WS_STR_UUID, hash);
#else
String k = key + WS_STR_UUID;
String k;
k.reserve(key.length() + WS_STR_UUID_LEN);
k += key;
k += WS_STR_UUID;
SHA1Builder sha1;
sha1.begin();
sha1.add((const uint8_t*)k.c_str(), k.length());
@@ -1323,8 +1307,6 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket
addHeader(WS_STR_CONNECTION, WS_STR_UPGRADE);
addHeader(WS_STR_UPGRADE, F("websocket"));
addHeader(WS_STR_ACCEPT,buffer);
free(buffer);
free(hash);
}
void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request)
@@ -1334,7 +1316,7 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request)
request->client()->close(true);
return;
}
String out = _assembleHead(request->version());
String out(_assembleHead(request->version()));
request->client()->write(out.c_str(), _headLength);
_state = RESPONSE_WAIT_ACK;
}

View File

@@ -54,6 +54,8 @@
#define DEFAULT_MAX_WS_CLIENTS 4
#endif
using AsyncWebSocketSharedBuffer = std::shared_ptr<std::vector<uint8_t>>;
class AsyncWebSocket;
class AsyncWebSocketResponse;
class AsyncWebSocketClient;
@@ -93,13 +95,13 @@ class AsyncWebSocketMessageBuffer {
friend AsyncWebSocketClient;
private:
std::shared_ptr<std::vector<uint8_t>> _buffer;
AsyncWebSocketSharedBuffer _buffer;
public:
AsyncWebSocketMessageBuffer();
AsyncWebSocketMessageBuffer(size_t size);
AsyncWebSocketMessageBuffer(uint8_t* data, size_t size);
~AsyncWebSocketMessageBuffer();
AsyncWebSocketMessageBuffer(){}
explicit AsyncWebSocketMessageBuffer(size_t size);
AsyncWebSocketMessageBuffer(const uint8_t* data, size_t size);
//~AsyncWebSocketMessageBuffer();
bool reserve(size_t size);
uint8_t* get() { return _buffer->data(); }
size_t length() const { return _buffer->size(); }
@@ -108,7 +110,7 @@ class AsyncWebSocketMessageBuffer {
class AsyncWebSocketMessage
{
private:
std::shared_ptr<std::vector<uint8_t>> _WSbuffer;
AsyncWebSocketSharedBuffer _WSbuffer;
uint8_t _opcode{WS_TEXT};
bool _mask{false};
AwsMessageStatus _status{WS_MSG_ERROR};
@@ -117,7 +119,7 @@ private:
size_t _acked{};
public:
AsyncWebSocketMessage(std::shared_ptr<std::vector<uint8_t>> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false);
bool finished() const { return _status != WS_MSG_SENDING; }
bool betweenFrames() const { return _acked == _ack; }
@@ -146,7 +148,7 @@ class AsyncWebSocketClient {
uint32_t _keepAlivePeriod;
void _queueControl(uint8_t opcode, const uint8_t *data=NULL, size_t len=0, bool mask=false);
void _queueMessage(std::shared_ptr<std::vector<uint8_t>> buffer, uint8_t opcode=WS_TEXT, bool mask=false);
void _queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false);
void _runQueue();
void _clearQueue();
@@ -204,7 +206,7 @@ class AsyncWebSocketClient {
}
//data packets
void message(std::shared_ptr<std::vector<uint8_t>> buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); }
void message(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); }
bool queueIsFull() const;
size_t queueLen() const;
@@ -213,20 +215,24 @@ class AsyncWebSocketClient {
size_t printf_P(PGM_P formatP, ...) __attribute__ ((format (printf, 2, 3)));
#endif
void text(std::shared_ptr<std::vector<uint8_t>> buffer);
void text(AsyncWebSocketSharedBuffer buffer);
void text(const uint8_t *message, size_t len);
void text(const char *message, size_t len);
void text(const char *message);
void text(const String &message);
#ifndef ESP32
void text(const __FlashStringHelper *message);
#endif // ESP32
void text(AsyncWebSocketMessageBuffer *buffer);
void binary(std::shared_ptr<std::vector<uint8_t>> buffer);
void binary(AsyncWebSocketSharedBuffer buffer);
void binary(const uint8_t *message, size_t len);
void binary(const char * message, size_t len);
void binary(const char * message);
void binary(const String &message);
#ifndef ESP32
void binary(const __FlashStringHelper *message, size_t len);
#endif // ESP32
void binary(AsyncWebSocketMessageBuffer *buffer);
bool canSend() const;
@@ -240,8 +246,8 @@ class AsyncWebSocketClient {
void _onData(void *pbuf, size_t plen);
};
typedef std::function<bool(AsyncWebServerRequest *request)> AwsHandshakeHandler;
typedef std::function<void(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len)> AwsEventHandler;
using AwsHandshakeHandler = std::function<bool(AsyncWebServerRequest *request)>;
using AwsEventHandler = std::function<void(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len)>;
//WebServer Handler implementation that plays the role of a socket server
class AsyncWebSocket: public AsyncWebHandler {
@@ -249,14 +255,15 @@ class AsyncWebSocket: public AsyncWebHandler {
String _url;
std::list<AsyncWebSocketClient> _clients;
uint32_t _cNextId;
AwsEventHandler _eventHandler;
AwsHandshakeHandler _handshakeHandler;
AwsEventHandler _eventHandler{nullptr};
AwsHandshakeHandler _handshakeHandler;
bool _enabled;
AsyncWebLock _lock;
public:
AsyncWebSocket(const String& url);
~AsyncWebSocket();
explicit AsyncWebSocket(const char* url) : _url(url) ,_cNextId(1), _enabled(true) {}
AsyncWebSocket(const String& url) :_url(url) ,_cNextId(1),_enabled(true) {}
~AsyncWebSocket(){};
const char * url() const { return _url.c_str(); }
void enable(bool e){ _enabled = e; }
bool enabled() const { return _enabled; }
@@ -265,7 +272,7 @@ class AsyncWebSocket: public AsyncWebHandler {
size_t count() const;
AsyncWebSocketClient * client(uint32_t id);
bool hasClient(uint32_t id){ return client(id) != NULL; }
bool hasClient(uint32_t id){ return client(id) != nullptr; }
void close(uint32_t id, uint16_t code=0, const char * message=NULL);
void closeAll(uint16_t code=0, const char * message=NULL);
@@ -278,33 +285,41 @@ class AsyncWebSocket: public AsyncWebHandler {
void text(uint32_t id, const char *message, size_t len);
void text(uint32_t id, const char *message);
void text(uint32_t id, const String &message);
#ifndef ESP32
void text(uint32_t id, const __FlashStringHelper *message);
#endif // ESP32
void text(uint32_t id, AsyncWebSocketMessageBuffer *buffer);
void text(uint32_t id, std::shared_ptr<std::vector<uint8_t>> buffer);
void text(uint32_t id, AsyncWebSocketSharedBuffer buffer);
void textAll(const uint8_t *message, size_t len);
void textAll(const char * message, size_t len);
void textAll(const char * message);
void textAll(const String &message);
#ifndef ESP32
void textAll(const __FlashStringHelper *message);
#endif // ESP32
void textAll(AsyncWebSocketMessageBuffer *buffer);
void textAll(std::shared_ptr<std::vector<uint8_t>> buffer);
void textAll(AsyncWebSocketSharedBuffer buffer);
void binary(uint32_t id, const uint8_t *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 String &message);
#ifndef ESP32
void binary(uint32_t id, const __FlashStringHelper *message, size_t len);
#endif // ESP32
void binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer);
void binary(uint32_t id, std::shared_ptr<std::vector<uint8_t>> buffer);
void binary(uint32_t id, AsyncWebSocketSharedBuffer buffer);
void binaryAll(const uint8_t *message, size_t len);
void binaryAll(const char *message, size_t len);
void binaryAll(const char *message);
void binaryAll(const String &message);
#ifndef ESP32
void binaryAll(const __FlashStringHelper *message, size_t len);
#endif // ESP32
void binaryAll(AsyncWebSocketMessageBuffer *buffer);
void binaryAll(std::shared_ptr<std::vector<uint8_t>> buffer);
void binaryAll(AsyncWebSocketSharedBuffer buffer);
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)));
@@ -333,7 +348,7 @@ class AsyncWebSocket: public AsyncWebHandler {
// messagebuffer functions/objects.
AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0);
AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size);
AsyncWebSocketMessageBuffer * makeBuffer(const uint8_t * data, size_t size);
const std::list<AsyncWebSocketClient> &getClients() const { return _clients; }
};