diff --git a/components/esp_websocket_client/esp_websocket_client.c b/components/esp_websocket_client/esp_websocket_client.c index 953a7b1d29..37eeb1a7cc 100644 --- a/components/esp_websocket_client/esp_websocket_client.c +++ b/components/esp_websocket_client/esp_websocket_client.c @@ -1146,6 +1146,17 @@ esp_err_t esp_websocket_client_start(esp_websocket_client_handle_t client) } esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client) +{ + esp_err_t result = esp_websocket_client_initiate_stop(client); + if (result != ESP_OK) + return result; + + xEventGroupWaitBits(client->status_bits, STOPPED_BIT, false, true, portMAX_DELAY); + client->state = WEBSOCKET_STATE_UNKNOW; + return ESP_OK; +} + +esp_err_t esp_websocket_client_initiate_stop(esp_websocket_client_handle_t client) { if (client == NULL) { return ESP_ERR_INVALID_ARG; @@ -1162,13 +1173,30 @@ esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client) return ESP_FAIL; } - client->run = false; - xEventGroupWaitBits(client->status_bits, STOPPED_BIT, false, true, portMAX_DELAY); - client->state = WEBSOCKET_STATE_UNKNOW; + return ESP_OK; } +bool esp_websocket_client_is_already_stopped(esp_websocket_client_handle_t client) +{ + if (client == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (client->run) + return false; + + EventBits_t bits = xEventGroupClearBits(client->status_bits, 0); + if (bits & STOPPED_BIT) + { + client->state = WEBSOCKET_STATE_UNKNOW; + return true; + } + + return false; +} + static int esp_websocket_client_send_close(esp_websocket_client_handle_t client, int code, const char *additional_data, int total_len, TickType_t timeout) { uint8_t *close_status_data = NULL; diff --git a/components/esp_websocket_client/include/esp_websocket_client.h b/components/esp_websocket_client/include/esp_websocket_client.h index 15fb63b7ca..d60149df47 100644 --- a/components/esp_websocket_client/include/esp_websocket_client.h +++ b/components/esp_websocket_client/include/esp_websocket_client.h @@ -212,6 +212,38 @@ esp_err_t esp_websocket_client_start(esp_websocket_client_handle_t client); */ esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client); +/** + * @brief Initiate an asynchronus stop of the WebSocket connection without + * websocket closing handshake + * + * This API initiates a non-blocking asynchronus stop of ws client. This will + * close TCP connection later directly without sending close frames. This is + * method is similar to esp_websocket_client_stop() but does not block the calling + * task. It is required to then later periodically call + * esp_websocket_client_is_already_stopped() to find out when its done and to + * finalize the closing of the websocket client. + * + * Notes: + * - Cannot be called from the websocket event handler + * + * @param[in] client The client + * + * @return esp_err_t + */ +esp_err_t esp_websocket_client_initiate_stop(esp_websocket_client_handle_t client); + +/** + * @brief After an asynchronus stop was initiated, this method returns if it is done already. + * If this method returns true, it also performed some final cleanup. It should then not + * be called anymore unless esp_websocket_client_initiate_stop() is called again. + * + * @param[in] client The client + * + * @return + * - bool if it is done or not + */ +bool esp_websocket_client_is_already_stopped(esp_websocket_client_handle_t client); + /** * @brief Destroy the WebSocket connection and free all resources. * This function must be the last function to call for an session.