ArduinoWebsockets icon indicating copy to clipboard operation
ArduinoWebsockets copied to clipboard

Websocket Client Became Slower and Unstable After Upgrading ESP32 from 1.0.4 to 1.0.6

Open IMikhelson opened this issue 3 years ago • 1 comments

Describe the bug Websocket client receiving binary data is slow (slower than before) and randomly goes into a cycle of closing and opening the socket, thus rendering communication impossible, and is unable to recover.

To Reproduce Steps to reproduce the behavior. This should include:

  • The library version you are using: 0.5.3
  • The board you are using: ESP32 (ESP-WROOM-32)
  • Information about other components in the system (do you use third party client/server software?): I use a Python Tornado websocket server.
  1. Start Tornado server (which just sends images from the webcam in real time).
  2. Initialize wifi and connect to websocket server from ESP32.
  3. Receive data stream and render on LED matrix (although that is turned off currently to isolate websocket).

Expected behavior I am not sending huge amounts of data, so I expect the websocket to be fast and stable.

Code Here is the relevant ESP32 code. Most of it is just to create a milliseconds timestamp (using the ezTime library) to compare to the one I send from the Tornado server. The websocket loop task is running with priority 2, whereas every other task is priority 1.

uint64_t recreate_timestamp_from_bytes(const char * t) {
  uint64_t value = 
    static_cast<uint64_t>(t[0]) |
    static_cast<uint64_t>(t[1]) << 8 |
    static_cast<uint64_t>(t[2]) << 16 |
    static_cast<uint64_t>(t[3]) << 24 |
    static_cast<uint64_t>(t[4]) << 32 |
    static_cast<uint64_t>(t[5]) << 40 |
    static_cast<uint64_t>(t[6]) << 48 |
    static_cast<uint64_t>(t[7]) << 56;

  return value;
}

void onMessageCallback(WebsocketsMessage message) {
   static uint32_t counter = 0;
   Serial.print("Got Message (");
   Serial.print(counter++, DEC);
   Serial.print("): ");
   const char* payload = message.c_str();
   uint64_t timestamp_ws = recreate_timestamp_from_bytes(payload + 12288);
   uint64_t my_ms = ms(TIME_NOW);
   uint64_t my_now = now();
   uint64_t timestamp = my_now*1000 + my_ms;
   Serial.println((int64_t)timestamp-(int64_t)timestamp_ws, DEC);

void websocket_loop_task(void * parameters) {
  while (1) {
    if (socket_open) {
      websocket_client.poll();
    }
    vTaskDelay(2);
  }
}

Additional context I am building a real time video stream from my computer's webcam to an LED matrix. I am sending images (12288 bytes) from the Tornado websocket server to the ESP32 client, which then renders the image on my LED matrix. I first ran this in the Arduino IDE and it ran flawlessly (i.e. I was receiving images at ~33 frames/sec with no latency and completely stable). Then, I ported the code to VS Code (Platformio) and it became slow (i.e. larger and larger delay as time goes on) and unstable. The only difference in environments was that my Arduino IDE was running an old version of the esp32 board (1.0.4). When I updated that version (without changing any code), I started encountering the same issues (slow and unstable). Worse yet, reverting back to 1.0.4 did not fix the issue.

At this point, to test, I am just sending images with an appended timestamp from the Tornado server at ~33 fps. I am not rendering anything on the LED matrix, just to isolate the websockets. When I throttle the sending rate to around 20 fps, there is not a delay on the websockets, but they still crash randomly and are unable to recover without resetting the ESP32.

IMikhelson avatar Feb 22 '22 22:02 IMikhelson

As a followup, I ran two more tests:

  1. I connected a websocket and sent nothing (just to check connection stability), and it remained open with no issues for 12 hours.
  2. I connected a websocket and sent one message every second (so quite slowly), and it crashed again in the same way as described in the issue. The amount of time from starting to crashing seems random, as the first time it sent about 20 messages before crashing, and the second it send about 900. As before, once it crashes, it is unable to recover. So it looks like the stability issue is unrelated to speed of the communication.

IMikhelson avatar Feb 23 '22 19:02 IMikhelson