Links2004 / arduinoWebSockets

arduinoWebSockets
GNU Lesser General Public License v2.1
1.89k stars 556 forks source link

Failed to transfer large data packets #435

Open HelloDB opened 5 years ago

HelloDB commented 5 years ago

Hi! Thanks for a great library. Trying to send image data quickly from WebSocket, but failed Is it feasible to send 50kbyte*15frame mjpg per second using esp8266 or esp32? Esp8266 takes about 0.3 seconds to transfer 50kb,Esp32 often reports an error during continuous transmission: "No more processes". First of all, how can I solve the problem of sending a single image? I would appreciate any help! Below is the test code:


// WEBSOCKETS_MAX_DATA_SIZE  (120*1024) // Change WebSockets.h:60

#include <Arduino.h>

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiMulti.h>

#include <WebSocketsServer.h>

WiFiMulti WiFiMulti;
WebSocketsServer webSocket = WebSocketsServer(81);

#define USE_SERIAL Serial

void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
    const uint8_t *src = (const uint8_t *)mem;
    USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
    for (uint32_t i = 0; i < len; i++) {
        if (i % cols == 0) {
            USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
        }
        USE_SERIAL.printf("%02X ", *src);
        src++;
    }
    USE_SERIAL.printf("\n");
}

void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {

    switch (type) {
    case WStype_DISCONNECTED:
        USE_SERIAL.printf("[%u] Disconnected!\n", num);
        break;
    case WStype_CONNECTED: {
        IPAddress ip = webSocket.remoteIP(num);
        USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
        webSocket.sendTXT(num, "Connected");
    } break;
    case WStype_TEXT:
        USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
        break;
    case WStype_BIN:
        Serial.print(".");
        // USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
        // hexdump(payload, length);
        break;
    case WStype_ERROR:
    case WStype_FRAGMENT_TEXT_START:
    case WStype_FRAGMENT_BIN_START:
    case WStype_FRAGMENT:
    case WStype_FRAGMENT_FIN:
        break;
    }
}

void setup() {
    USE_SERIAL.begin(115200);
    USE_SERIAL.setDebugOutput(true);
    for (uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

    WiFiMulti.addAP("CMCC-333", "@123456789@");

    while (WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
    }
    Serial.println(WiFi.localIP());
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);
}

void loop() {
    webSocket.loop();
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>websocket</title>
</head>

<body>

    <a href="javascript:WebSocketConnect()">Connect</a><br />
    <a href="javascript:WebSocketClose()">Close</a><br />
    <a href="javascript:WebSocketSend()">Send</a><br />
    <script>
        var ws;
        function WebSocketConnect() {
            ws = new WebSocket("ws://192.168.1.6:81/"); // 
            ws.onopen = function () {
                ws.send("hello esp!");
            };
            ws.onmessage = function (evt) {
                var received_msg = evt.data;
                console.log("Received:",received_msg);
            };
            ws.onclose = function () {
                console.log("Disconnected!");
            };
        }
        function WebSocketClose() {
            ws.close();
        }

        function WebSocketSend() {

            // var arrayBuffer = new ArrayBuffer(1024 * 113);
            // var x = new Uint8Array(arrayBuffer);
            // ws.binaryType = 'arraybuffer';
            // ws.send(arrayBuffer);

            var block = 1024;
            var count = 113;
            while (count--) {
                var arrayBuffer = new ArrayBuffer(block);
                var x = new Uint8Array(arrayBuffer);
                ws.binaryType = 'arraybuffer';
                ws.send(arrayBuffer);
            }

        }

    </script>
</body>

</html>

190513-1

Links2004 commented 5 years ago

please enable debug in the Arduino IDE to get more detailed log output. may the ESP is overloaded and you need to send the data at a lower rate, or implement a ACK and only send more data when you get the ACK.

HelloDB commented 5 years ago

I found that the LWIP_HIGHER_BANDWIDTH configuration of esp8266 can get faster speed, so I use esp8266 temporarily. I don't know if ESP32's continuous transmission capability is stronger. I will continue to test esp32 when using more pixel screens.

don41382 commented 5 years ago

I have the same issue. I am constantly transmitting 4kB frames at a rate fo 30 frames per second. So roughly 120kB/second. It works for a while (20 seconds) but stops with the same error:

[E][WiFiClient.cpp:455] flush(): fail on fd 58, errno: 11, "No more processes"

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
  switch (type) {
    case WStype_BIN: {
      // do nothing
      break;
 }
void loop() {
  webSocket.loop();
  delay(10);
}

Arduino-System: Lolin32

I would also like to know what a possible fix could be. Thanks!

don41382 commented 5 years ago

Can anyone help?

Even if you don't register a event listener this error happens.

I would shout pizzas and beers for a solution. :-)