Open electrical-pro opened 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?
@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:
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.
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.
@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
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:
@Links2004 Ok, I use OpenWRT on my router. Here are Wireshark packets: packets.zip (I've disconnected the internet two times during capturing)
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
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.
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:
.....
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;
......
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);
}
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();
.....
}
Serial
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?