Links2004 / arduinoWebSockets

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

WebSocketsServer memory leak? #75

Open bnh129 opened 8 years ago

bnh129 commented 8 years ago

I would like to create and destroy a WebSocketsServer on-demand, however based on the following test code, there appears to be a memory leak.

#include <Hash.h>
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>

WebSocketsServer *ws;

int t_next, t_now;

void handleWs(uint8_t num, WStype_t type, uint8_t *payload, size_t len) {
  switch(type) {
    case WStype_DISCONNECTED:
      Serial1.println("disc");
      break;
    case WStype_CONNECTED:
      Serial1.println("conn");
      break;
    case WStype_TEXT:
      Serial1.println("recv");
      break;
  }
}

void setup() {

  Serial1.begin(115200);
  Serial1.println();

  WiFi.disconnect(true);
  WiFi.softAPdisconnect(true);
  WiFi.persistent(false);

  delay(1000);

  WiFi.mode(WIFI_AP);
  WiFi.softAP("TestAP", "testpass");

  delay(1000);

  ws = new WebSocketsServer(80);
  ws->onEvent(handleWs);
  ws->begin();

  t_next = millis();
}

void loop() {

  t_now = millis();

  if (t_now - t_next >= 0) {
    //ws->disconnect();
    delete ws;

    delay(100);

    ws = new WebSocketsServer(80);
    ws->onEvent(handleWs);
    ws->begin();

    Serial1.println("Heap: " + String(ESP.getFreeHeap()));

    t_next = millis() + 1000;
  }

  ws->loop();
}
bnh129 commented 8 years ago

I've tried similar test code with https://github.com/me-no-dev/ESPAsyncWebServer and it seems to exhibit the same behaviour, making me suspect this is a lower level issue. Has anyone experienced similar behaviour?

everslick commented 8 years ago

i currently see a mem leak of ~180 bytes on each new websocket connection, i don't destroy or recreate the server itself. i just open and close websockets from the browser to the ESP8266. i can do this until i run out of heap memory.

everslick commented 8 years ago

memory returns after a minute, that means that the connection is in close_wait state the "fix" is to force abort the connection after it's closed (in the TCP lib, not the WebSocket one)

everslick commented 8 years ago

The following sketch reproduces the bug. point your browser to the IP and press reload a few times. see the heap decreasing by 184 bytes each time. wait a minute to see heap chunks return.

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

extern "C" {
#include "user_interface.h"
}

WebSocketsServer ws(81, "", "leak");
ESP8266WebServer http(80);

void handleRoot() {
  char buf[256];

  snprintf_P(buf, sizeof (buf), PSTR("\
    <!DOCTYPE html>\n\
    <html><head>\n\
    </head><body>\n\
    <script>\n\
      ws = new WebSocket('ws://%s:81/', ['leak']);\n\
    </script>\n\
    free heap = %i bytes\n\
    </body></html>\n\
  "), WiFi.localIP().toString().c_str(), system_get_free_heap_size());

  http.send(200, "text/html", buf);
}

void handleWs(uint8_t num, WStype_t type, uint8_t *payload, size_t len) {
  switch(type) {
    case WStype_DISCONNECTED:
      Serial.println("WS: disconnected");
      break;
    case WStype_CONNECTED:
      Serial.println("WS: connected");
      break;
    case WStype_TEXT:
      Serial.println("WS: receive");
      break;
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();

  delay(1000);

  WiFi.mode(WIFI_STA);
  WiFi.begin("yourssid", "yourpw");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  http.on("/", handleRoot);

  ws.onEvent(handleWs);
  ws.begin();
  http.begin();
  Serial.println("server started");
}

void loop() {
  ws.loop();
  http.handleClient();
}
antoniosap commented 5 years ago

we have 2 subnets 192.168.147.x and 192.168.146.x if a web socket is open and i change subnet then the esp 8266 have a huge memory lekage

Links2004 commented 5 years ago

can you verify that its the lib an not the TCP stack? simply create a TCP server / client on open a connection.

yashodeepk commented 3 years ago

Hey, I am getting the same issue if I run sample code and monitor the heap memory, there is a loss of 48 byte in around 20-30 min for running every time.

Please need a help here!