Skip to content

Commit 861cb66

Browse files
committed
feat(websocket): Create specific Event for PONG message
- Separate the PONG message from generic payload, this can make it easier to identify when a timeout occur when receiving a payload
1 parent 39e2333 commit 861cb66

File tree

5 files changed

+27
-1
lines changed

5 files changed

+27
-1
lines changed

components/esp_websocket_client/esp_websocket_client.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,11 @@ static esp_err_t esp_websocket_client_recv(esp_websocket_client_handle_t client)
984984
return ESP_OK;
985985
}
986986

987-
esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DATA, client->rx_buffer, rlen);
987+
if (client->last_opcode == WS_TRANSPORT_OPCODES_PONG) {
988+
esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_PONG, client->rx_buffer, rlen);
989+
} else {
990+
esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DATA, client->rx_buffer, rlen);
991+
}
988992

989993
client->payload_offset += rlen;
990994
} while (client->payload_offset < client->payload_len);

components/esp_websocket_client/examples/linux/main/websocket_linux.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i
3030
break;
3131
case WEBSOCKET_EVENT_CONNECTED:
3232
ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED");
33+
esp_websocket_client_send_with_opcode((esp_websocket_client_handle_t)handler_args, WS_TRANSPORT_OPCODES_PING, NULL, 0, portMAX_DELAY);
3334
break;
3435
case WEBSOCKET_EVENT_DISCONNECTED:
3536
ESP_LOGI(TAG, "WEBSOCKET_EVENT_DISCONNECTED");
@@ -52,6 +53,9 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i
5253
// If received data contains json structure it succeed to parse
5354
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);
5455

56+
break;
57+
case WEBSOCKET_EVENT_PONG:
58+
ESP_LOGI(TAG, "WEBSOCKET_EVENT_PONG (op=%d, len=%d)", data->op_code, data->data_len);
5559
break;
5660
case WEBSOCKET_EVENT_ERROR:
5761
ESP_LOGI(TAG, "WEBSOCKET_EVENT_ERROR");

components/esp_websocket_client/examples/target/main/websocket_example.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i
7979
break;
8080
case WEBSOCKET_EVENT_CONNECTED:
8181
ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED");
82+
esp_websocket_client_send_with_opcode((esp_websocket_client_handle_t)handler_args, WS_TRANSPORT_OPCODES_PING, NULL, 0, portMAX_DELAY);
8283
break;
8384
case WEBSOCKET_EVENT_DISCONNECTED:
8485
ESP_LOGI(TAG, "WEBSOCKET_EVENT_DISCONNECTED");
@@ -114,6 +115,12 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i
114115

115116
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);
116117

118+
xTimerReset(shutdown_signal_timer, portMAX_DELAY);
119+
break;
120+
case WEBSOCKET_EVENT_PONG:
121+
ESP_LOGI(TAG, "WEBSOCKET_EVENT_PONG");
122+
ESP_LOGI(TAG, "Received opcode=%d", data->op_code);
123+
// Reset shutdown timer on PONG as well
117124
xTimerReset(shutdown_signal_timer, portMAX_DELAY);
118125
break;
119126
case WEBSOCKET_EVENT_ERROR:

components/esp_websocket_client/examples/target/pytest_websocket.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ def test_recv_fragmented_msg1(dut):
172172
def test_recv_fragmented_msg2(dut):
173173
dut.expect('websocket: Total payload length=2000, data_len=976, current payload offset=1024')
174174

175+
# Test for PONG message reception:
176+
# Verifies that the WebSocket client correctly receives a PONG response after sending a PING.
177+
# The PING is automatically sent when the connection is established.
178+
def test_pong_received(dut):
179+
dut.expect('WEBSOCKET_EVENT_PONG')
180+
print('\nPONG message received successfully\n')
181+
sys.stdout.flush()
182+
175183
# Test for receiving fragmented text messages:
176184
# Checks if the WebSocket can accurately reconstruct a message sent in several smaller parts.
177185
def test_fragmented_txt_msg(dut):
@@ -237,6 +245,7 @@ def test_fragmented_binary_msg(dut):
237245
dut.expect('Please enter uri of websocket endpoint', timeout=30)
238246
dut.write(uri)
239247
test_echo(dut)
248+
test_pong_received(dut)
240249
test_recv_long_msg(dut, ws, 2000, 3)
241250
test_json(dut, ws)
242251
test_fragmented_txt_msg(dut)
@@ -247,3 +256,4 @@ def test_fragmented_binary_msg(dut):
247256
else:
248257
print('DUT connecting to {}'.format(uri))
249258
test_echo(dut)
259+
test_pong_received(dut)

components/esp_websocket_client/include/esp_websocket_client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef enum {
3434
WEBSOCKET_EVENT_CONNECTED, /*!< Once the Websocket has been connected to the server, no data exchange has been performed */
3535
WEBSOCKET_EVENT_DISCONNECTED, /*!< The connection has been disconnected */
3636
WEBSOCKET_EVENT_DATA, /*!< When receiving data from the server, possibly multiple portions of the packet */
37+
WEBSOCKET_EVENT_PONG, /*!< When receiving a PONG control frame from the server */
3738
WEBSOCKET_EVENT_CLOSED, /*!< The connection has been closed cleanly */
3839
WEBSOCKET_EVENT_BEFORE_CONNECT, /*!< The event occurs before connecting */
3940
WEBSOCKET_EVENT_BEGIN, /*!< The event occurs once after thread creation, before event loop */

0 commit comments

Comments
 (0)