esp8266-react icon indicating copy to clipboard operation
esp8266-react copied to clipboard

websocket (WS_EVT_DATA) event from client does not update state on esp8266 only

Open tichaonax opened this issue 3 years ago • 1 comments

On esp8266 the event handler from file

lib\framework\WebSocketTxRx.h

is not passed the correct size_t len. As a result the if condition to proceed with updating the state is never executed. This works well on esp32 and I cannot figure out if its a library issue or not. I have a json size 1365 characters but the len passed is 528.

  virtual void onWSEvent(AsyncWebSocket* server,
                         AsyncWebSocketClient* client,
                         AwsEventType type,
                         void* arg,
                         uint8_t* data,
                         size_t len) {
    if (type == WS_EVT_DATA) {
      Serial.println(F("WS_EVT_DATA"));
      AwsFrameInfo* info = (AwsFrameInfo*)arg;
      if (info->final && info->index == 0 && info->len == len) {

lib_deps =
  ArduinoJson@>=6.0.0,<7.0.0
  ; The following allows the use of the latest code for ESPAsyncWebServer - there hasn't been a release in a while
  ; Work around for https://github.com/me-no-dev/ESPAsyncWebServer/issues/1151
  https://github.com/me-no-dev/ESPAsyncWebServer
  ;ESP Async WebServer@>=1.2.0,<2.0.0
  AsyncMqttClient@>=0.9.0,<1.0.0

tichaonax avatar Jun 24 '22 22:06 tichaonax

Same with ESP32, it called with:

  • info->final = 1
  • info->index = 0
  • info->len = 1605
  • len = 1428

then again, with:

  • info->final = 1
  • info->index = 1428
  • info->len = 1605
  • len = 177

So, **info->len ** if a length of whole message, len is how many bytes was received this time, info->index is index of data received in message.

I'm not sure what info->final is (both times it is 1, I expected it to be 0 in first chunk and 1 in last), but this function waits for complete message in one chunk, and cannot assemble message from two or more parts.

I have added

#define RCV_BUFFER_SIZE 4096
unsigned char rcv_buffer[RCV_BUFFER_SIZE];

just before onWSEvent function and modified its content:

 if (info->len > RCV_BUFFER_SIZE) return;
 memcpy(rcv_buffer + info->index, data, len);
 if ((info->index + len) == info->len) {
     if (info->opcode == WS_TEXT) {
         DynamicJsonDocument jsonDocument = DynamicJsonDocument(WebSocketConnector<T>::_bufferSize);
         DeserializationError error = deserializeJson(jsonDocument, (char*)rcv_buffer);
         if (!error && jsonDocument.is<JsonObject>()) {
             JsonObject jsonObject = jsonDocument.as<JsonObject>();
             WebSocketConnector<T>::_statefulService->update(
             jsonObject, _stateUpdater, WebSocketConnector<T>::clientId(client));
         }
     }
 }

so it can assemble message in separate buffer before deserialization in cost of memory usage.

king2 avatar Aug 03 '22 23:08 king2