diff --git a/components/esp_websocket_client/esp_websocket_client.c b/components/esp_websocket_client/esp_websocket_client.c index 5ad2e11b2c..98f50eec15 100644 --- a/components/esp_websocket_client/esp_websocket_client.c +++ b/components/esp_websocket_client/esp_websocket_client.c @@ -990,7 +990,11 @@ static esp_err_t esp_websocket_client_recv(esp_websocket_client_handle_t client) return ESP_OK; } - esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DATA, client->rx_buffer, rlen); + if (client->last_opcode == WS_TRANSPORT_OPCODES_PONG) { + esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_PONG, client->rx_buffer, rlen); + } else { + esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DATA, client->rx_buffer, rlen); + } client->payload_offset += rlen; } while (client->payload_offset < client->payload_len); diff --git a/components/esp_websocket_client/examples/linux/main/websocket_linux.c b/components/esp_websocket_client/examples/linux/main/websocket_linux.c index 3329274fbc..ea44597025 100644 --- a/components/esp_websocket_client/examples/linux/main/websocket_linux.c +++ b/components/esp_websocket_client/examples/linux/main/websocket_linux.c @@ -30,6 +30,7 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i break; case WEBSOCKET_EVENT_CONNECTED: ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED"); + esp_websocket_client_send_with_opcode((esp_websocket_client_handle_t)handler_args, WS_TRANSPORT_OPCODES_PING, NULL, 0, portMAX_DELAY); break; case WEBSOCKET_EVENT_DISCONNECTED: ESP_LOGI(TAG, "WEBSOCKET_EVENT_DISCONNECTED"); @@ -52,6 +53,9 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i // If received data contains json structure it succeed to parse ESP_LOGW(TAG, "Total payload length=%d, data_len=%d, current payload offset=%d\r\n", data->payload_len, data->data_len, data->payload_offset); + break; + case WEBSOCKET_EVENT_PONG: + ESP_LOGI(TAG, "WEBSOCKET_EVENT_PONG (op=%d, len=%d)", data->op_code, data->data_len); break; case WEBSOCKET_EVENT_ERROR: ESP_LOGI(TAG, "WEBSOCKET_EVENT_ERROR"); diff --git a/components/esp_websocket_client/examples/target/main/websocket_example.c b/components/esp_websocket_client/examples/target/main/websocket_example.c index 31998527b5..e4e9d2b8d1 100644 --- a/components/esp_websocket_client/examples/target/main/websocket_example.c +++ b/components/esp_websocket_client/examples/target/main/websocket_example.c @@ -79,6 +79,8 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i break; case WEBSOCKET_EVENT_CONNECTED: ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED"); + // Optional: Send ping to keep the connection alive. + esp_websocket_client_send_with_opcode((esp_websocket_client_handle_t)handler_args, WS_TRANSPORT_OPCODES_PING, NULL, 0, portMAX_DELAY); break; case WEBSOCKET_EVENT_DISCONNECTED: ESP_LOGI(TAG, "WEBSOCKET_EVENT_DISCONNECTED"); @@ -116,6 +118,9 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i xTimerReset(shutdown_signal_timer, portMAX_DELAY); break; + case WEBSOCKET_EVENT_PONG: + ESP_LOGI(TAG, "WEBSOCKET_EVENT_PONG"); + break; case WEBSOCKET_EVENT_ERROR: ESP_LOGI(TAG, "WEBSOCKET_EVENT_ERROR"); log_error_if_nonzero("HTTP status code", data->error_handle.esp_ws_handshake_status_code); diff --git a/components/esp_websocket_client/examples/target/pytest_websocket.py b/components/esp_websocket_client/examples/target/pytest_websocket.py index dd59384d44..d1b91e7d91 100644 --- a/components/esp_websocket_client/examples/target/pytest_websocket.py +++ b/components/esp_websocket_client/examples/target/pytest_websocket.py @@ -89,11 +89,23 @@ def test_examples_protocol_websocket(dut): 3. send and receive data """ + # Test for connection: + # Verifies that the WebSocket client correctly connected. + def test_connected(dut): + dut.expect('WEBSOCKET_EVENT_CONNECTED') + print('Received CONNECTED') + + # Test for PONG functionality: + # Verifies that the WebSocket client correctly receives a PONG response after sending a PING. + # The PING is automatically sent when the connection is established. + def test_pong(dut): + dut.expect('WEBSOCKET_EVENT_PONG') + print('Received PONG') + # Test for echo functionality: # Sends a series of simple "hello" messages to the WebSocket server and verifies that each one is echoed back correctly. # This tests the basic responsiveness and correctness of the WebSocket connection. def test_echo(dut): - dut.expect('WEBSOCKET_EVENT_CONNECTED') for i in range(0, 5): dut.expect(re.compile(b'Received=hello (\\d)')) print('All echos received') @@ -236,6 +248,8 @@ def test_fragmented_binary_msg(dut): print('DUT connecting to {}'.format(uri)) dut.expect('Please enter uri of websocket endpoint', timeout=30) dut.write(uri) + test_connected(dut) + test_pong(dut) test_echo(dut) test_recv_long_msg(dut, ws, 2000, 3) test_json(dut, ws) @@ -246,4 +260,6 @@ def test_fragmented_binary_msg(dut): test_close(dut) else: print('DUT connecting to {}'.format(uri)) + test_connected(dut) + test_pong(dut) test_echo(dut) diff --git a/components/esp_websocket_client/include/esp_websocket_client.h b/components/esp_websocket_client/include/esp_websocket_client.h index c125a6e350..ac1e0c0ff4 100644 --- a/components/esp_websocket_client/include/esp_websocket_client.h +++ b/components/esp_websocket_client/include/esp_websocket_client.h @@ -34,6 +34,7 @@ typedef enum { 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_PONG, /*!< When receiving a PONG control frame from the server, Pong events might carry payload when present. */ 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 */