Reverted Websocket Code to previous commit

This commit is contained in:
2025-12-26 10:02:41 +02:00
parent 7d9bc42078
commit 8d397c6dd5
2 changed files with 29 additions and 68 deletions

View File

@@ -105,83 +105,53 @@ void WebSocketServer::onConnect(AsyncWebSocketClient* client) {
void WebSocketServer::onDisconnect(AsyncWebSocketClient* client) { void WebSocketServer::onDisconnect(AsyncWebSocketClient* client) {
LOG_INFO("WebSocket client #%u disconnected", client->id()); 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.removeClient(client->id());
_clientManager.cleanupDisconnectedClients(); _clientManager.cleanupDisconnectedClients();
} }
void WebSocketServer::onData(AsyncWebSocketClient* client, void* arg, uint8_t* data, size_t len) { void WebSocketServer::onData(AsyncWebSocketClient* client, void* arg, uint8_t* data, size_t len) {
AwsFrameInfo* info = (AwsFrameInfo*)arg; AwsFrameInfo* info = (AwsFrameInfo*)arg;
uint32_t clientId = client->id();
// Only handle complete, single-frame text messages
// Use message_opcode to get the actual message type (not the frame opcode) if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
uint8_t messageOpcode = info->message_opcode; // Allocate buffer for payload
char* payload = (char*)malloc(len + 1);
// Only handle TEXT and BINARY messages if (!payload) {
if (messageOpcode != WS_TEXT && messageOpcode != WS_BINARY) { LOG_ERROR("Failed to allocate memory for WebSocket payload");
LOG_DEBUG("WebSocket client #%u: ignoring non-text/binary message (opcode: %u)", clientId, messageOpcode); String errorResponse = ResponseBuilder::error("memory_error", "Out of memory");
return; _clientManager.sendToClient(client->id(), errorResponse);
} 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);
} }
buffer.opcode = messageOpcode; memcpy(payload, data, len);
buffer.lastUpdate = millis(); payload[len] = '\0';
if (info->len > len) { LOG_DEBUG("WebSocket client #%u sent: %s", client->id(), payload);
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());
// Parse JSON // Parse JSON
StaticJsonDocument<2048> doc; StaticJsonDocument<2048> doc;
DeserializationError error = deserializeJson(doc, completeMessage); DeserializationError error = deserializeJson(doc, payload);
if (error) { 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"); String errorResponse = ResponseBuilder::error("parse_error", "Invalid JSON");
_clientManager.sendToClient(clientId, errorResponse); _clientManager.sendToClient(client->id(), errorResponse);
} else { } else {
// Update client last seen time // Update client last seen time
_clientManager.updateClientLastSeen(clientId); _clientManager.updateClientLastSeen(client->id());
// Call user callback if set // Call user callback if set
if (_messageCallback) { if (_messageCallback) {
LOG_DEBUG("Routing message from client #%u to callback handler", clientId); LOG_DEBUG("Routing message from client #%u to callback handler", client->id());
_messageCallback(clientId, doc); _messageCallback(client->id(), doc);
} else { } else {
LOG_WARNING("WebSocket message received but no callback handler is set!"); 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());
} }
} }

View File

@@ -22,7 +22,6 @@
#include <Arduino.h> #include <Arduino.h>
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <map>
#include "../../ClientManager/ClientManager.hpp" #include "../../ClientManager/ClientManager.hpp"
class WebSocketServer { class WebSocketServer {
@@ -78,14 +77,6 @@ private:
ClientManager& _clientManager; ClientManager& _clientManager;
MessageCallback _messageCallback; MessageCallback _messageCallback;
// Fragment reassembly buffer (stores incomplete messages per client)
struct FragmentBuffer {
String data;
uint8_t opcode;
unsigned long lastUpdate;
};
std::map<uint32_t, FragmentBuffer> _fragmentBuffers;
/** /**
* @brief Static WebSocket event handler * @brief Static WebSocket event handler
*/ */