Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disconnection detection issue #864

Open
ScreamZ opened this issue Jan 5, 2024 · 11 comments
Open

Disconnection detection issue #864

ScreamZ opened this issue Jan 5, 2024 · 11 comments

Comments

@ScreamZ
Copy link

ScreamZ commented Jan 5, 2024

Hi,

I'm working on a disconnect scenario to improve the documentation and my workflow.

My computer is running a WebSocket server.
The ESP32 is the client. (WebSocketsClient webSocket;)

1 - Disconnected from server shutdown

✅ Seems to work properly and properly detected by the library.

2 - Switching the network from the server

To simulate disconnection, I also switched off the WiFi on my computer, so the server is no longer reachable.
This is an edge case I guess but why can't this happen?

The ESP32 with socket doesn't detect the disconnection. Within onEvent -> WStype_DISCONNECTED

Current workaround

Currently, I'm pinging frequently the server and if the last message is > 10 seconds, I consider it off.

Do you think the library can handle this scenario of failure without having to rely on custom code for pings?

@Links2004
Copy link
Owner

Links2004 commented Jan 5, 2024

the ESP tcp socket only notices that the socket is dead when something is send.
if you try to send something or enableHeartbeat sends its ping.

void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount);

after a send failes the client disconnects and the event for WStype_DISCONNECTED is send.

the websocket has a ping build in and it can be enabled with enableHeartbeat so no need for custom ping/pong.

backround:
if you hard disconnect the network on the servers side no FIN/ACK from the server side can be send and as a result the ESP TCP stack never gets the "info" that the server is gone.
we are left only with the ACK timout on TX to detect this if the server is simply gone and does not answer any more.

@AviStudio
Copy link

Tell me please, how long can a WebSocket Client connection be? I would like to send some sensor data over it in JSON, and the scenario is that sensor should be online 24/7

@Links2004
Copy link
Owner

there is no limit on the arduinoWebSockets side, it all depends on how your server is setup and how stable the WiFi / Network connection is.
I my self use this lib in home automation tasks and with the heartbeat enabled I had never problems with long dead connections.

@AviStudio
Copy link

I would be very happy if you could share an example how to use heartbeat.
In another way I would like to ask if there are some possible limits or problems if I'll send data over WebSocket in JSON format, maybe I should do some RAM cleanup or something else?

@ScreamZ
Copy link
Author

ScreamZ commented Jan 12, 2024

I would be very happy if you could share an example how to use heartbeat. In another way I would like to ask if there are some possible limits or problems if I'll send data over WebSocket in JSON format, maybe I should do some RAM cleanup or something else?

I could only recommend using https://arduinojson.org/, on ESP32 there is no real RAM concern as they have a lot.

@Links2004
Copy link
Owner

Links2004 commented Jan 12, 2024

yes using JSON is works with ESP8266 and ESP32 fine.

e.g.

            DynamicJsonDocument doc(1024);
            DeserializationError error = deserializeJson(doc, payload, length);
            if(error) {
                USE_SERIAL.print(F("deserializeJson() failed: "));
                USE_SERIAL.println(error.c_str());
                return;
            }

heartbeat only needs to be enabled.

void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount);

@AviStudio
Copy link

AviStudio commented Jan 13, 2024

Hello again. Here i have a few questions:

  1. Where should i call client.enableHeartbeat()? in "setup" will be ok? or in "loop" ?
  2. pingInterval, pongTimeout are in milliseconds?

@Links2004
Copy link
Owner

yes client.enableHeartbeat is called in the setup process, and yes all times are in milliseconds.

/**
* enable ping/pong heartbeat process
* @param pingInterval uint32_t how often ping will be sent
* @param pongTimeout uint32_t millis after which pong should timout if not received
* @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect
*/
void WebSocketsClient::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) {
WebSockets::enableHeartbeat(&_client, pingInterval, pongTimeout, disconnectTimeoutCount);
}

@AviStudio
Copy link

@Links2004 for "client" this solution seems to work fine. How about the same scenario but for "server" (I'm testing an ESP32 with WebSocket server behind NAT (Internet->Router(NAT)->Switch->ESP32 w LAN) and if i pull out the cable between Router and Switch, how can "server" handle that?

@Links2004
Copy link
Owner

any reason to not use enableHeartbeat there too?

void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount);

each side can send a ping, the ws protocol allows it.

https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2

@slowpoison4
Copy link

Hi Links2004,
ive been using the enable heartBeat for ESP32 for my ws client. What i notice is that randomly the websocket crashes (which is fine) but then i notice the Heap memory starts to decline quite rapidly. When i removed the enable heartbeat and manually shut of the internet using a mobile hotspot, i didnt notice any heap memory reduction. It only happens when using enable heartbeat. Also further more, when the reconnection does happen, the lost heap memory isnt returned and eventually the heap memory becomes so low that i get no more process for wifi and then it crashes. My current workaround is to restart the esp when a disconnection is detected. This is less than ideal as this could cause missing some sensor data during the intial setup phase. Any suggestions as to why this is happening?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants