Links2004 / arduinoWebSockets

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

"case WStype_DISCONNECTED:" never called after the internet connection is lost. #363

Open electrical-pro opened 6 years ago

electrical-pro commented 6 years ago

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WebSocketsClient.h>
#include <Hash.h>

ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;

long ChechGoogleMillis = 0;

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

    switch(type) {
        case WStype_DISCONNECTED:
            Serial.printf("[WSc] Disconnected!\n");
            break;
        case WStype_CONNECTED: {
            Serial.printf("[WSc] Connected to url: %s\n", payload);

            // send message to server when Connected
            webSocket.sendTXT("Connected");
        }
            break;
        case WStype_TEXT:
            Serial.printf("[WSc] get text: %s\n", payload);

            // send message to server
            // webSocket.sendTXT("message here");
            break;
        case WStype_BIN:
            Serial.printf("[WSc] get binary length: %u\n", length);
            hexdump(payload, length);

            // send data to server
            // webSocket.sendBIN(payload, length);
            break;
    }

}

void setup() {

  Serial.begin(19200);
  Serial.println();

  delay(1000);
  WiFi.mode(WIFI_STA);

   IPAddress ip(192, 168, 4, 213);
   IPAddress gateway(192, 168, 4, 1);
   IPAddress subnet(255, 255, 255, 0);
   IPAddress dnsAdrr(8, 8, 8, 8);
   WiFi.config(ip, gateway, subnet, dnsAdrr);

  WiFiMulti.addAP("MyNetwork", "MyPassword");

    while(WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
    }
  Serial.println("wi-fi connected.");

    // server address, port and URL
    webSocket.begin("echo.websocket.org", 80, "/");

    // event handler
    webSocket.onEvent(webSocketEvent);

    // try ever 5000 again if connection has failed
    webSocket.setReconnectInterval(5000);

}

void loop() {
  webSocket.loop();

  // check google, in order to check internet
  if (WiFiMulti.run() == WL_CONNECTED && millis() > ChechGoogleMillis + 30000) {
    ChechGoogleMillis=millis();
    HTTPClient http;
    Serial.println("=================");
    Serial.println("[HTTP] begin...");
    http.begin("http://google.com"); //HTTP    
    int httpCode = http.GET();
    Serial.printf("[HTTP] GET... code: %d\n", httpCode);
    if(httpCode>0){
      Serial.println("[HTTP] Google OK");
    }else{
    Serial.println("[HTTP] Google ERROR"); 
    }
    http.end();

    // send some data via websocket
    Serial.println("Sending to websocket...");
    webSocket.sendTXT("WS TEXT TO SEND");
    Serial.println("Done");
  }

}

Serial

wi-fi connected.
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
Done
[WSc] Connected to url: /
[WSc] get text: Connected
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
Done
[WSc] get text: WS TEXT TO SEND
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
Done
[WSc] get text: WS TEXT TO SEND
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
Done
[WSc] get text: WS TEXT TO SEND
=================
[HTTP] begin...                           
[HTTP] GET... code: -1                                            // connection is lost
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1                                             // no connection for 1 minute
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...                                                   
[HTTP] GET... code: -1                                    // no connection for 2 minute
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1                                  // no connection for 3 minute
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
Done
=================
[HTTP] begin...
[HTTP] GET... code: 301                             // after 4 minus I connected the internet
[HTTP] Google OK
Sending to websocket...
Done
[WSc] Disconnected!                                   // only now it is called.
[WSc] Connected to url: /
[WSc] get text: Connected
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
Done
[WSc] get text: WS TEXT TO SEND

As you can see after the connection is lost, case WStype_DISCONNECTED: is not called. The sketch 8 times tried to send text via WebSocket using: webSocket.sendTXT("WS TEXT TO SEND"); but nothing...

But eventually, it gets called... but only after connection to internet is re-established. As you can see I connected the internet after 4 minus and only after that "disconnect" gets called. Why so?

Links2004 commented 6 years ago

the TCP stack of the ESP can only detect that the connection is dead when you try to send something. if I get your code correct

WiFiMulti.run() == WL_CONNECTED

will prevent the

 webSocket.sendTXT("WS TEXT TO SEND");

so you never call the send function --> result the ESP TCP stack can not detect that the socket is down --> no event.

can you try to call sendTXT every time and not only when the WiFi state is WL_CONNECTED?

electrical-pro commented 6 years ago

@Links2004 Hi, Thanks for your answer. But my code prints "Sending to WebSocket..." & "Done" which means that this part is executed:

    Serial.println("Sending to websocket...");
    webSocket.sendTXT("WS TEXT TO SEND");
    Serial.println("Done");

So yes, I call the send function: webSocket.sendTXT("WS TEXT TO SEND"); every time. I probably did not explain what I did properly... I did not turn the wi-fi off in my router, I only disconnected the internet cable. It means that WiFiMulti.run() is always == WL_CONNECTED.

WiFiMulti.run() == WL_CONNECTED detects connection to WI-Fi, not to the internet. Correct? And in my case wi-fi remains connected, I only disconnect the internet cable from my router.

What my code does:

  1. Checks wi-fi. (wi-fi is always on in my case, so WiFiMulti.run() == WL_CONNECTED always true)
  2. The code tries to request google.com (I did this just to test connection to the internet. If code: 301 it means Google is accessible. If code: -1 it means Google not accessible... we can see code -1 is because I disconnected the internet cable from the router).
  3. The code tries to send text via WebSocket.
  4. The code repeats all above every 30 seconds.

My code 8 times executed webSocket.sendTXT("WS TEXT TO SEND"); but case WStype_DISCONNECTED: was not called. Only after 4 minutes when I eventually decided to connect the internet cable to my router, only then case WStype_DISCONNECTED: was called.

can you try to call sendTXT every time and not only when the WiFi state is WL_CONNECTED?

That is the problem. WiFi state is WL_CONNECTED even if my internet is down. But how do I know if my internet is down using just WS client? case WStype_DISCONNECTED: it is not called when internet goes down.

Links2004 commented 6 years ago

ok now I get it. can you enable the debug output in the IDE, then we can see what the TCP stack is reporting in this case. may we can find a way to fix the Problem.

electrical-pro commented 6 years ago

@Links2004 ok, no problem. When you see [HTTP] GET... code: -1 it means I disconnected the internet. As you can see we get [WSc] Disconnected! only after I connected the internet back again. Hope it helps, Thank you.


SDK:2.2.1(cfd48f3)/Core:2.4.2/lwIP:2.0.3(STABLE-2_0_3_RELEASE/glue:arduino-2.4.1-13-g163bb82)/BearSSL:6d1cefc

scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 

connected with W-Network, channel 11
dhcp client start...
state: 5 -> 0 (0)
rm 0
scandone
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 

connected with W-Network, channel 11
ip:192.168.4.213,mask:255.255.255.0,gw:192.168.4.1
ip:192.168.4.213,mask:255.255.255.0,gw:192.168.4.1
wi-fi connected.
[WS-Client] connect ws...
[WS-Client] connection to echo.websocket.org:80 Faild
[WS-Client] client disconnected.
[WSc] Disconnected!
pm open,type:2 0
[WS-Client] connect ws...
[WS-Client] connected to echo.websocket.org:80.
[WS-Client][sendHeader] sending header...
[WS-Client][sendHeader] handshake GET / HTTP/1.1
Host: echo.websocket.org:80
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: fApV9351tHgpQbBwHzOLrw==
Sec-WebSocket-Protocol: arduino
Origin: file://
User-Agent: arduino-WebSocket-Client

[write] n: zu t: 248
[WS-Client][sendHeader] sending header... Done (140068us).
[WS-Client][handleHeader] RX: HTTP/1.1 101 Web Socket Protocol Handshake
[WS-Client][handleHeader] RX: Access-Control-Allow-Credentials: true
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: content-type
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: authorization
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: x-websocket-extensions
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: x-websocket-version
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: x-websocket-protocol
[WS-Client][handleHeader] RX: Access-Control-Allow-Origin: null
[WS-Client][handleHeader] RX: Connection: Upgrade
[WS-Client][handleHeader] RX: Date: Fri, 07 Sep 2018 13:22:56 GMT
[WS-Client][handleHeader] RX: Sec-WebSocket-Accept: OSjmOXzb6Uxj3HcR1Bow70jteDY=
[WS-Client][handleHeader] RX: Server: Kaazing Gateway
[WS-Client][handleHeader] RX: Upgrade: websocket
[WS-Client][handleHeader] Header read fin.
[WS-Client][handleHeader] Client settings:
[WS-Client][handleHeader]  - cURL: /
[WS-Client][handleHeader]  - cKey: fApV9351tHgpQbBwHzOLrw==
[WS-Client][handleHeader] Server header:
[WS-Client][handleHeader]  - cCode: 101
[WS-Client][handleHeader]  - cIsUpgrade: 1
[WS-Client][handleHeader]  - cIsWebsocket: 1
[WS-Client][handleHeader]  - cAccept: OSjmOXzb6Uxj3HcR1Bow70jteDY=
[WS-Client][handleHeader]  - cProtocol: arduino
[WS-Client][handleHeader]  - cExtensions: 
[WS-Client][handleHeader]  - cVersion: 0
[WS-Client][handleHeader]  - cSessionId: 
[WS-Client][handleHeader] Websocket connection init done.
[WS][0][headerDone] Header Handling Done.
[WSc] Connected to url: /
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 9 headerToPayload: 0
[WS][0][sendFrame] text: Connected
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 15
[WS][0][sendFrame] sending Frame Done (13928us).
[WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0
[readCb] n: zu t: 2
[WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1
[WS][0][handleWebsocket] ------- read massage frame -------
[WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0  opCode: 1
[WS][0][handleWebsocket] mask: 0 payloadLen: 9
[readCb] n: zu t: 9
[WS][0][handleWebsocket] text: Connected
[WSc] get text: Connected
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (12944us).
Done
[WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0
[readCb] n: zu t: 2
[WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1
[WS][0][handleWebsocket] ------- read massage frame -------
[WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0  opCode: 1
[WS][0][handleWebsocket] mask: 0 payloadLen: 15
[readCb] n: zu t: 15
[WS][0][handleWebsocket] text: WS TEXT TO SEND
[WSc] get text: WS TEXT TO SEND
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (12873us).
Done
[WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0
[readCb] n: zu t: 2
[WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1
[WS][0][handleWebsocket] ------- read massage frame -------
[WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0  opCode: 1
[WS][0][handleWebsocket] mask: 0 payloadLen: 15
[readCb] n: zu t: 15
[WS][0][handleWebsocket] text: WS TEXT TO SEND
[WSc] get text: WS TEXT TO SEND
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (13066us).
Done
[WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0
[readCb] n: zu t: 2
[WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1
[WS][0][handleWebsocket] ------- read massage frame -------
[WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0  opCode: 1
[WS][0][handleWebsocket] mask: 0 payloadLen: 15
[readCb] n: zu t: 15
[WS][0][handleWebsocket] text: WS TEXT TO SEND
[WSc] get text: WS TEXT TO SEND
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (13966us).
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (14447us).
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (11957us).
Done
=================
[HTTP] begin...
[HTTP] GET... code: -1
[HTTP] Google ERROR
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (14309us).
Done
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (13245us).
Done
[WS-Client] connection lost.
[WS-Client] client disconnected.
[WSc] Disconnected!
[WS-Client] connect ws...
[WS-Client] connected to echo.websocket.org:80.
[WS-Client][sendHeader] sending header...
[WS-Client][sendHeader] handshake GET / HTTP/1.1
Host: echo.websocket.org:80
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: PnawozPVJjkIFXKZ3Zrxaw==
Sec-WebSocket-Protocol: arduino
Origin: file://
User-Agent: arduino-WebSocket-Client

[write] n: zu t: 248
[WS-Client][sendHeader] sending header... Done (140218us).
[WS-Client][handleHeader] RX: HTTP/1.1 101 Web Socket Protocol Handshake
[WS-Client][handleHeader] RX: Access-Control-Allow-Credentials: true
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: content-type
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: authorization
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: x-websocket-extensions
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: x-websocket-version
[WS-Client][handleHeader] RX: Access-Control-Allow-Headers: x-websocket-protocol
[WS-Client][handleHeader] RX: Access-Control-Allow-Origin: null
[WS-Client][handleHeader] RX: Connection: Upgrade
[WS-Client][handleHeader] RX: Date: Fri, 07 Sep 2018 13:26:42 GMT
[WS-Client][handleHeader] RX: Sec-WebSocket-Accept: OlE1bnLiHB11f+gsEz5MvGW/MSk=
[WS-Client][handleHeader] RX: Server: Kaazing Gateway
[WS-Client][handleHeader] RX: Upgrade: websocket
[WS-Client][handleHeader] Header read fin.
[WS-Client][handleHeader] Client settings:
[WS-Client][handleHeader]  - cURL: /
[WS-Client][handleHeader]  - cKey: PnawozPVJjkIFXKZ3Zrxaw==
[WS-Client][handleHeader] Server header:
[WS-Client][handleHeader]  - cCode: 101
[WS-Client][handleHeader]  - cIsUpgrade: 1
[WS-Client][handleHeader]  - cIsWebsocket: 1
[WS-Client][handleHeader]  - cAccept: OlE1bnLiHB11f+gsEz5MvGW/MSk=
[WS-Client][handleHeader]  - cProtocol: arduino
[WS-Client][handleHeader]  - cExtensions: 
[WS-Client][handleHeader]  - cVersion: 0
[WS-Client][handleHeader]  - cSessionId: 
[WS-Client][handleHeader] Websocket connection init done.
[WS][0][headerDone] Header Handling Done.
[WSc] Connected to url: /
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 9 headerToPayload: 0
[WS][0][sendFrame] text: Connected
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 15
[WS][0][sendFrame] sending Frame Done (13507us).
[WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0
[readCb] n: zu t: 2
[WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1
[WS][0][handleWebsocket] ------- read massage frame -------
[WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0  opCode: 1
[WS][0][handleWebsocket] mask: 0 payloadLen: 9
[readCb] n: zu t: 9
[WS][0][handleWebsocket] text: Connected
[WSc] get text: Connected
=================
[HTTP] begin...
[HTTP] GET... code: 301
[HTTP] Google OK
Sending to websocket...
[WS][0][sendFrame] ------- send message frame -------
[WS][0][sendFrame] fin: 1 opCode: 1 mask: 1 length: 15 headerToPayload: 0
[WS][0][sendFrame] text: WS TEXT TO SEND
[WS][0][sendFrame] pack to one TCP package...
[write] n: zu t: 21
[WS][0][sendFrame] sending Frame Done (12856us).
Done
[WS][0][handleWebsocketWaitFor] size: 2 cWsRXsize: 0
[readCb] n: zu t: 2
[WS][0][handleWebsocketWaitFor][readCb] size: 2 ok: 1
[WS][0][handleWebsocket] ------- read massage frame -------
[WS][0][handleWebsocket] fin: 1 rsv1: 0 rsv2: 0 rsv3 0  opCode: 1
[WS][0][handleWebsocket] mask: 0 payloadLen: 15
[readCb] n: zu t: 15
[WS][0][handleWebsocket] text: WS TEXT TO SEND
[WSc] get text: WS TEXT TO SEND
Links2004 commented 6 years ago

ok its clearly a TCP layer problem, there are checks if the connection is there in the code path on multible paces: https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSocketsClient.cpp#L196 https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L88 https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L625 but all of them getting the info that the TCP socket is still fine and working.

on of two thinks can be the problem:

electrical-pro commented 6 years ago

@Links2004 Ok, I use OpenWRT on my router. Here are Wireshark packets: packets.zip (I've disconnected the internet two times during capturing)

picc

My second router at 192.168.3.1, on which I disconnect the internet, sends "destination unreachable". I don't know whether that is the packet that we are looking for.

https://github.com/Links2004/arduinoWebSockets/issues/373 Similar

electrical-pro commented 5 years ago

I tried adding webSocket.enableHeartbeat(15000, 3000, 2); and now it works. But it is still unknown why I had the issue in the first place.

TuxRobotics commented 5 years ago

I can confirm the callback is not being called. It seems WebSocketsClient.cpp immediately tries to reconnect and never calls the disconnected callback. This can be seen by enabling debugging for ArduinoWebsockets and ESPAsyncTCP, which shows the async onDisconnect callback firing:

[WS][0][sendFrame] pack to one TCP package...
[write] n: %zu t: 419
[WS][0][sendFrame] sending Frame Done (1578us).
[A-TCP] onDisconnect
[WS-Server][0] Disconnect client
[WS-Client] asyncConnect...
[WS-Client] connection to XXXXXXX Faild
[WS-Client] asyncConnect...
[WS-Client] connection to XXXXXXX Faild

The asyncConnect fires very rapidly, every few milliseconds.

Here WebSocketClient.cpp line 694 handles the async onDisconnect callback, but does not trigger the WStype_DISCONNECTED event.

I tested this solution and it worked well:

  1. Add a flag to the client object in WebSockets.h around line 266:
        .....
        bool cHttpHeadersValid; ///< non-websocket http header validity indicator
        size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count

#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
        String cHttpLine;   ///< HTTP header lines
        bool   cWasDisconnected;
#endif

} WSclient_t;

......
  1. Set the flag in WebSocketsClient.cpp around line 686
void WebSocketsClient::connectedCb() {

    DEBUG_WEBSOCKETS("[WS-Client] connected to %s:%u.\n", _host.c_str(), _port);

#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
    _client.tcp->onDisconnect(std::bind([](WebSocketsClient * c, AsyncTCPbuffer * obj, WSclient_t * client) -> bool {
                        DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num);

                        client->status = WSC_NOT_CONNECTED;
                        client->tcp = NULL;
                        client->cWasDisconnected = true; //Tell the asyncConnect() function to call the DISCONECTED callback

                        // reconnect
                        c->asyncConnect();

                        return true;
                    }, this, std::placeholders::_1, &_client));
#endif

    _client.status = WSC_HEADER;

#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC)
    // set Timeout for readBytesUntil and readStringUntil
    _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT);
#endif

#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266)
    _client.tcp->setNoDelay(true);

    if(_client.isSSL && _fingerprint.length()) {
        if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) {
            DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n");
            WebSockets::clientDisconnect(&_client, 1000);
            return;
        }
    }
#endif

    // send Header to Server
    sendHeader(&_client);

}
  1. In asyncConnect, check and reset the flag after calling the callback:
void WebSocketsClient::asyncConnect() {

    DEBUG_WEBSOCKETS("[WS-Client] asyncConnect...\n");

    //Call the callback if the client was just disconnected
    if (_client.cWasDisconnected) {
        runCbEvent(WStype_DISCONNECTED, NULL, 0);
        _client.cWasDisconnected = false;
    }

    AsyncClient * tcpclient = new AsyncClient();

   .....
}