diff --git a/components/esp_websocket_client/esp_websocket_client.c b/components/esp_websocket_client/esp_websocket_client.c index 6ef0818365..6445c9cbfe 100644 --- a/components/esp_websocket_client/esp_websocket_client.c +++ b/components/esp_websocket_client/esp_websocket_client.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -80,6 +80,7 @@ typedef struct { char *auth; int port; bool auto_reconnect; + bool close_reconnect; void *user_context; int network_timeout_ms; char *subprotocol; @@ -376,6 +377,7 @@ static esp_err_t esp_websocket_client_set_config(esp_websocket_client_handle_t c if (config->disable_auto_reconnect) { cfg->auto_reconnect = false; } + cfg->close_reconnect = config->enable_close_reconnect; if (config->disable_pingpong_discon) { cfg->pingpong_timeout_sec = 0; @@ -1127,10 +1129,21 @@ static void esp_websocket_client_task(void *pv) } 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; + if (client->config->close_reconnect && xSemaphoreTakeRecursive(client->lock, lock_timeout) == pdPASS) { + client->state = WEBSOCKET_STATE_WAIT_TIMEOUT; + client->error_handle.error_type = WEBSOCKET_ERROR_TYPE_SERVER_CLOSE; + esp_transport_close(client->transport); + esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_CLOSED, NULL, 0); + client->reconnect_tick_ms = _tick_get_ms(); + ESP_LOGI(TAG, "Reconnect after %d ms", client->wait_timeout_ms); + xEventGroupClearBits(client->status_bits, STOPPED_BIT | CLOSE_FRAME_SENT_BIT); + xSemaphoreGiveRecursive(client->lock); + } else { + client->run = false; + client->state = WEBSOCKET_STATE_UNKNOW; + esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_CLOSED, NULL, 0); + break; + } } } diff --git a/components/esp_websocket_client/include/esp_websocket_client.h b/components/esp_websocket_client/include/esp_websocket_client.h index 07093119dd..59013db525 100644 --- a/components/esp_websocket_client/include/esp_websocket_client.h +++ b/components/esp_websocket_client/include/esp_websocket_client.h @@ -48,7 +48,8 @@ typedef enum { WEBSOCKET_ERROR_TYPE_NONE = 0, WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT, WEBSOCKET_ERROR_TYPE_PONG_TIMEOUT, - WEBSOCKET_ERROR_TYPE_HANDSHAKE + WEBSOCKET_ERROR_TYPE_HANDSHAKE, + WEBSOCKET_ERROR_TYPE_SERVER_CLOSE } esp_websocket_error_type_t; /** @@ -101,6 +102,7 @@ typedef struct { const char *password; /*!< Using for Http authentication */ const char *path; /*!< HTTP Path, if not set, default is `/` */ bool disable_auto_reconnect; /*!< Disable the automatic reconnect function when disconnected */ + bool enable_close_reconnect; /*!< Enable reconnect after server close */ void *user_context; /*!< HTTP user data context */ int task_prio; /*!< Websocket task priority */ const char *task_name; /*!< Websocket task name */