diff --git a/docs/en/api-reference/protocols/esp_http_server.rst b/docs/en/api-reference/protocols/esp_http_server.rst index 76f17b77adc..86eaa5e4d38 100644 --- a/docs/en/api-reference/protocols/esp_http_server.rst +++ b/docs/en/api-reference/protocols/esp_http_server.rst @@ -139,6 +139,36 @@ To use the WebSocket post-handshake callback, you must enable :menuitem:`CONFIG_ httpd_register_uri_handler(server, &ws); +WebSocket Control Frame Handler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, the server replies to WebSocket control frames automatically — a PING frame is answered with a PONG and a CLOSE frame is answered with a CLOSE — without involving the application. Setting ``handle_ws_control_frames`` to true in :cpp:type:`httpd_uri_t` disables this behavior and delivers control frames to the data handler, which then becomes responsible for receiving the frame and sending the protocol replies itself. + +The ``ws_control_handler`` callback provides a middle ground: when it is set (and ``handle_ws_control_frames`` is true), control frames (PING, PONG, CLOSE) are delivered to this dedicated handler instead of the data handler, while the server still receives the frame body and performs the protocol replies itself after the handler returns. This is useful for observing heartbeats (tracking PONG responses) or logging the close reason without re-implementing the reply logic. + +The frame passed to the handler is read-only and owned by the server; it is only valid for the duration of the call, so the handler must not free or retain it. If the handler returns an error, the server still sends the protocol reply and then closes the connection. + +.. code-block:: c + + static esp_err_t ws_control_frame_handler(httpd_req_t *req, const httpd_ws_frame_t *frame) + { + // Observe PING/PONG/CLOSE here (e.g. heartbeat tracking, logging). + // The server sends the protocol reply itself after this returns. + return ESP_OK; + } + + // Registering a WebSocket URI handler with a dedicated control-frame handler + static const httpd_uri_t ws = { + .uri = "/ws", + .method = HTTP_GET, + .handler = handler, // Your WebSocket data handler + .user_ctx = NULL, + .is_websocket = true, + .handle_ws_control_frames = true, + .ws_control_handler = ws_control_frame_handler + }; + + Event Handling -------------- diff --git a/docs/zh_CN/api-reference/protocols/esp_http_server.rst b/docs/zh_CN/api-reference/protocols/esp_http_server.rst index d3223975d41..7ac96228bfb 100644 --- a/docs/zh_CN/api-reference/protocols/esp_http_server.rst +++ b/docs/zh_CN/api-reference/protocols/esp_http_server.rst @@ -139,6 +139,36 @@ WebSocket 握手后回调 httpd_register_uri_handler(server, &ws); +WebSocket 控制帧处理程序 +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +默认情况下,服务器会自动回复 WebSocket 控制帧——收到 PING 帧时回复 PONG 帧,收到 CLOSE 帧时回复 CLOSE 帧——应用程序不会参与该过程。若将 :cpp:type:`httpd_uri_t` 中的 ``handle_ws_control_frames`` 设置为 true,则会禁用该行为,控制帧将交由数据处理程序处理,此时应用程序需要自行接收控制帧并发送协议回复。 + +``ws_control_handler`` 回调提供了一种折中方案:设置该回调(且 ``handle_ws_control_frames`` 为 true)后,控制帧(PING、PONG、CLOSE)将交由该专用处理程序处理,而不再传递给数据处理程序;服务器仍会自行接收帧体,并在回调返回后自动发送协议回复。该机制适用于观测心跳(跟踪 PONG 响应)或记录连接关闭原因,而无需重新实现回复逻辑。 + +传递给该回调的帧为只读,且由服务器持有,仅在回调调用期间有效,因此回调中不得释放或保留该帧。如果回调返回错误,服务器仍会发送协议回复,然后关闭连接。 + +.. code-block:: c + + static esp_err_t ws_control_frame_handler(httpd_req_t *req, const httpd_ws_frame_t *frame) + { + // 在此处观测 PING/PONG/CLOSE 帧(例如心跳跟踪、日志记录) + // 回调返回后,服务器会自行发送协议回复 + return ESP_OK; + } + + // 注册带有专用控制帧处理程序的 WebSocket URI 处理程序 + static const httpd_uri_t ws = { + .uri = "/ws", + .method = HTTP_GET, + .handler = handler, // WebSocket 数据处理程序 + .user_ctx = NULL, + .is_websocket = true, + .handle_ws_control_frames = true, + .ws_control_handler = ws_control_frame_handler + }; + + 事件处理 --------------