-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Websocket client disconnects and never reconnects (IDFGH-13129) #14072
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
Comments
@hitecSmartHome Thank you for raising this question. I attempted to reproduce the issue, but I was unable to. I executed both the client and server, and observed that the client successfully sent a connect event. When I shut down the server, I noticed that the client attempted to reconnect. I tried
|
Unfortunately, the debug output isn't very helpful, but I've still got a hunch here. It might be the same issue as in espressif/arduino-esp32#9712, where the hostname couldn't be resolved anymore after automatically switching to IPv6. I experienced a similar problem with connections dropping after about half an hour to two hours, leading to a loop that required a reset. Best regards... |
Thank you for your help. if (data->op_code == 0x08 && data->data_len == 2) {
Serial.println("[WebsocketClient] - Got Close data");
return;
} After my ESP got this message, It does not see any clean close initiation and nothing. When I try to close it after this data packet, it does not work also. I have tried to destroy the ws client, tried to just stop it and tried to disconnect from it. Nothing works. The ESP is stuck in this state and can never reconnect. Doesn't even try to in itself. |
My case is similar to this #10657 I also can't reinit the wifi because I'm using wired ethernet. void WebsocketClient::init() {
client = esp_websocket_client_init(&config);
esp_websocket_register_events(
client,
WEBSOCKET_EVENT_ANY,
reinterpret_cast<esp_event_handler_t>(eventHandler),
static_cast<void*>(this));
esp_websocket_client_start(client);
}
bool WebsocketClient::reInit(){
esp_err_t err = esp_websocket_client_destroy(client);
if(err != ESP_OK){
return false;
}
init();
return true;
} I have tried to call reinit after a timer when I got this close frame, no help. |
But I thought we were talking about the ESP32-WROVER-E? Where do you plug in the Ethernet cable? ;) |
Into an rj45 socket ;) |
Okay, I wasn't aware that the ESP32WROVER-E could also be used as an Ethernet controller, when using an external physical interface device (PHY). So far, it was mainly a WLAN/Bluetooth module for me. I have now taken a closer look at the technical specifications. I also assumed that the IPv6/DNS problem described in arduino-esp32/issues/9712 is more likely related to the WLAN functionality, as the described misbehavior has only been reported in this context there, ...as far as I know. But the Arduino-ESP32 doesn't have an RJ45 socket, so there should be fewer ethernet problems with this configuration of course. ;) However, I could well imagine that the ESP32 also exhibits such behavior when working as an Ethernet controller. Perhaps it partially uses the same program libraries or similar functions for ethernet and wifi. Now the question is: Is your ESP32 maybe trying to connect to the router using IPv6 even though you haven't enabled it? This could explain why it's not working properly, since it might get a response over IPv6 from the Router but actually is using IPv4 only. I therefore recommend checking this or activating IPv6 to see if the described behavior persists. |
Thank you for the help really. I dont understand how this is related. The websocket connects fine initially and it can reconnect when it gets a clean close or in almost any other case. Will check the ipv6 options regardless. |
Well, if the ESP32 briefly informs your router (at some point, during operation) that it is reachable with its MAC address a1:b2:c3:xy under an IPv6 address now, the router will remember this IPv6 address for a while for the corresponding MAC address and will send its response to the IPv6 address. However, the ESP32 receives nothing because it is only reachable via IPv4. That's the theory, at least. Maybe it could also help, to deactivate IPv6 in the Router. I don't know. |
Iam on arduino 2.0.17 and idf 4.4.7. |
Also my router does not have any IPV6 settings. I can enable the ipv6 interface of the ethernet as well as the wifi hovewer. ETH.begin(
ETH8720_PHY_ADDR,
PIN_PHY_POWER,
PIN_SMI_MDC,
PIN_SMI_MDIO,
ETH_PHY_LAN8720,
ETH_CLK_MODE
);
ETH.enableIpV6(); This calls bool ETHClass::enableIpV6()
{
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH) == 0;
} |
Sorry, Is there a specific reason for using the older ESP-IDF v4.4? Please note that it will reach its end of life this July. The latest stable version of ESP-IDF is v5.3, and the latest stable ESP WebSocket client can be found here: ESP WebSocket Client v1.2.3. Anyway, I tried to reproduce the issue using the example with ESP-IDF v4.4, and it seems to work correctly as it attempts to reconnect after receiving a close message from the server. Have you tested this example? Here is the link for reference: GitHub Issue #14072. |
The specific reason is that Espressif don't want to support PIO at all so the guys are lacking behind. This happens only when the server sends a close DATA message and not a clean close. On clean close it reconnects fine. void WebsocketClient::handleWebSocketData(esp_websocket_event_data_t* data) {
if (data->op_code == 0x08 && data->data_len == 2) {
printf("[WebsocketClient] - Got Close data\n");
return;
}
} And it does not help even if I reinit the websocket client. void WebsocketClient::init() {
client = esp_websocket_client_init(&config);
esp_websocket_register_events(
client,
WEBSOCKET_EVENT_ANY,
reinterpret_cast<esp_event_handler_t>(eventHandler),
static_cast<void*>(this));
esp_websocket_client_start(client);
}
bool WebsocketClient::reInit(){
esp_err_t err = esp_websocket_client_destroy(client);
if(err != ESP_OK){ return false; }
init();
return true;
} I have 4 ESP modules on test. Two of them using WIFI, two of them using Ethernet. |
Okay, one of the ESP with ethernet has gone offline after 3 hour and 57 min. It still thinks its connected but no traffic. The two with the wifi is ok so far |
Okay so we went back to this problem. We are on
|
I can see a possible route which leads to this. When we receive a } else if (client->last_opcode == WS_TRANSPORT_OPCODES_CLOSE) {
ESP_LOGD(TAG, "Received close frame");
client->state = WEBSOCKET_STATE_CLOSING;
} In this state we can trigger this logic else if (WEBSOCKET_STATE_CLOSING == client->state &&
(CLOSE_FRAME_SENT_BIT & xEventGroupGetBits(client->status_bits))) {
ESP_LOGD(TAG, " Waiting for TCP connection to be closed by the server");
int ret = esp_transport_ws_poll_connection_closed(client->transport, 1000);
if (ret == 0) {
ESP_LOGW(TAG, "Did not get TCP close within expected delay");
} else if (ret < 0) {
ESP_LOGW(TAG, "Connection terminated while waiting for clean TCP close");
}
client->run = false;
client->state = WEBSOCKET_STATE_UNKNOW;
esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_CLOSED, NULL, 0);
break;
} This sets So am I understanding this correctly, if the server signals a wss shutdown the whole thing just blows itself up and it will never tries to reconnect? I can see that it dispatches an even |
Please help. If I undersand this correctly: typedef enum {
WEBSOCKET_EVENT_ANY = -1,
WEBSOCKET_EVENT_ERROR = 0, /*!< This event occurs when there are any errors during execution */
WEBSOCKET_EVENT_CONNECTED, /*!< Once the Websocket has been connected to the server, no data exchange has been performed */
WEBSOCKET_EVENT_DISCONNECTED, /*!< The connection has been disconnected */
WEBSOCKET_EVENT_DATA, /*!< When receiving data from the server, possibly multiple portions of the packet */
WEBSOCKET_EVENT_CLOSED, /*!< The connection has been closed cleanly */
WEBSOCKET_EVENT_BEFORE_CONNECT, /*!< The event occurs before connecting */
WEBSOCKET_EVENT_BEGIN, /*!< The event occurs once after thread creation, before event loop */
WEBSOCKET_EVENT_FINISH, /*!< The event occurs once after event loop, before thread destruction */
WEBSOCKET_EVENT_MAX
} esp_websocket_event_id_t; When |
Answers checklist.
IDF version.
4.4.7
Espressif SoC revision.
ESP-32 Wrover-E revision v3.0
Operating System used.
Windows
How did you build your project?
VS Code IDE
If you are using Windows, please specify command line type.
None
Development Kit.
ESP-32 Wrover-E
Power Supply used.
External 3.3V
What is the expected behavior?
Websocket client should reconnect
What is the actual behavior?
Websocket client does not reconnect
Steps to reproduce.
Debug Logs.
More Information.
I'm using Arduino as a component of IDF with PlatformIO.
websocket config
I have tried to set a timer when the disconnect happens and reinit the socket after 30 sec
Does not help.
The text was updated successfully, but these errors were encountered: