From 8d397c6dd5fc8359476a7761b0ab0de12ac7e0e4 Mon Sep 17 00:00:00 2001 From: bonamin Date: Fri, 26 Dec 2025 10:02:41 +0200 Subject: [PATCH] Reverted Websocket Code to previous commit --- .../WebSocketServer/WebSocketServer.cpp | 88 ++++++------------- .../WebSocketServer/WebSocketServer.hpp | 9 -- 2 files changed, 29 insertions(+), 68 deletions(-) diff --git a/vesper/src/Communication/WebSocketServer/WebSocketServer.cpp b/vesper/src/Communication/WebSocketServer/WebSocketServer.cpp index c9ddb4a..7fa8420 100644 --- a/vesper/src/Communication/WebSocketServer/WebSocketServer.cpp +++ b/vesper/src/Communication/WebSocketServer/WebSocketServer.cpp @@ -105,83 +105,53 @@ void WebSocketServer::onConnect(AsyncWebSocketClient* client) { void WebSocketServer::onDisconnect(AsyncWebSocketClient* client) { LOG_INFO("WebSocket client #%u disconnected", client->id()); - - // Clean up any fragment buffer for this client - _fragmentBuffers.erase(client->id()); - + _clientManager.removeClient(client->id()); _clientManager.cleanupDisconnectedClients(); } void WebSocketServer::onData(AsyncWebSocketClient* client, void* arg, uint8_t* data, size_t len) { AwsFrameInfo* info = (AwsFrameInfo*)arg; - uint32_t clientId = client->id(); - - // Use message_opcode to get the actual message type (not the frame opcode) - uint8_t messageOpcode = info->message_opcode; - - // Only handle TEXT and BINARY messages - if (messageOpcode != WS_TEXT && messageOpcode != WS_BINARY) { - LOG_DEBUG("WebSocket client #%u: ignoring non-text/binary message (opcode: %u)", clientId, messageOpcode); - return; - } - - // NOTE: As of ESPAsyncWebServer v3.9.3, the library automatically unmasks the data - // before calling this handler. The 'data' pointer contains plain, unmasked bytes. - - // Handle fragmented messages - reassemble them - if (info->index == 0) { - // First chunk - create or reset buffer - FragmentBuffer& buffer = _fragmentBuffers[clientId]; - buffer.data = ""; - - if (info->len > 0 && info->len < 65536) { - buffer.data.reserve(info->len); + + // Only handle complete, single-frame text messages + if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) { + // Allocate buffer for payload + char* payload = (char*)malloc(len + 1); + if (!payload) { + LOG_ERROR("Failed to allocate memory for WebSocket payload"); + String errorResponse = ResponseBuilder::error("memory_error", "Out of memory"); + _clientManager.sendToClient(client->id(), errorResponse); + return; } - - buffer.opcode = messageOpcode; - buffer.lastUpdate = millis(); - - if (info->len > len) { - LOG_DEBUG("WebSocket client #%u: started fragmented message (%llu bytes total)", clientId, info->len); - } - } - - // Get or create buffer for this client - FragmentBuffer& buffer = _fragmentBuffers[clientId]; - - // Append this chunk to the buffer (data is already unmasked by the library) - buffer.data.concat((const char*)data, len); - buffer.lastUpdate = millis(); - - // Check if message is complete - if (info->final && buffer.data.length() >= info->len) { - String completeMessage = buffer.data; - uint8_t opcode = buffer.opcode; - _fragmentBuffers.erase(clientId); - - LOG_DEBUG("WebSocket client #%u sent (%u bytes): %s", - clientId, completeMessage.length(), completeMessage.c_str()); - + + memcpy(payload, data, len); + payload[len] = '\0'; + + LOG_DEBUG("WebSocket client #%u sent: %s", client->id(), payload); + // Parse JSON StaticJsonDocument<2048> doc; - DeserializationError error = deserializeJson(doc, completeMessage); - + DeserializationError error = deserializeJson(doc, payload); + if (error) { - LOG_ERROR("Failed to parse WebSocket JSON from client #%u: %s", clientId, error.c_str()); + LOG_ERROR("Failed to parse WebSocket JSON from client #%u: %s", client->id(), error.c_str()); String errorResponse = ResponseBuilder::error("parse_error", "Invalid JSON"); - _clientManager.sendToClient(clientId, errorResponse); + _clientManager.sendToClient(client->id(), errorResponse); } else { // Update client last seen time - _clientManager.updateClientLastSeen(clientId); - + _clientManager.updateClientLastSeen(client->id()); + // Call user callback if set if (_messageCallback) { - LOG_DEBUG("Routing message from client #%u to callback handler", clientId); - _messageCallback(clientId, doc); + LOG_DEBUG("Routing message from client #%u to callback handler", client->id()); + _messageCallback(client->id(), doc); } else { LOG_WARNING("WebSocket message received but no callback handler is set!"); } } + + free(payload); + } else { + LOG_WARNING("Received fragmented or non-text WebSocket message from client #%u - ignoring", client->id()); } } diff --git a/vesper/src/Communication/WebSocketServer/WebSocketServer.hpp b/vesper/src/Communication/WebSocketServer/WebSocketServer.hpp index 1b40d33..3af8085 100644 --- a/vesper/src/Communication/WebSocketServer/WebSocketServer.hpp +++ b/vesper/src/Communication/WebSocketServer/WebSocketServer.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include "../../ClientManager/ClientManager.hpp" class WebSocketServer { @@ -78,14 +77,6 @@ private: ClientManager& _clientManager; MessageCallback _messageCallback; - // Fragment reassembly buffer (stores incomplete messages per client) - struct FragmentBuffer { - String data; - uint8_t opcode; - unsigned long lastUpdate; - }; - std::map _fragmentBuffers; - /** * @brief Static WebSocket event handler */