Răsfoiți Sursa

fix(server): Fix websocket server not support handle multiple connections when client send CLOSE frame

Yuan Jian Min 3 ani în urmă
părinte
comite
293830a8ee

+ 6 - 0
components/esp_http_server/src/httpd_parse.c

@@ -753,6 +753,12 @@ esp_err_t httpd_req_new(struct httpd_data *hd, struct sock_db *sd)
              sd->ws_handler != NULL ? "Yes" : "No",
              sd->ws_handler != NULL ? "Yes" : "No",
              sd->ws_close ? "Yes" : "No");
              sd->ws_close ? "Yes" : "No");
     if (sd->ws_handshake_done && sd->ws_handler != NULL) {
     if (sd->ws_handshake_done && sd->ws_handler != NULL) {
+        if (sd->ws_close == true) {
+            /* WS was marked as close state, do not deal with this socket */
+            ESP_LOGD(TAG, LOG_FMT("WS was marked close"));
+            return ESP_OK;
+        }
+
         ret = httpd_ws_get_frame_type(r);
         ret = httpd_ws_get_frame_type(r);
         ESP_LOGD(TAG, LOG_FMT("New WS request from existing socket, ws_type=%d"), ra->ws_type);
         ESP_LOGD(TAG, LOG_FMT("New WS request from existing socket, ws_type=%d"), ra->ws_type);
 
 

+ 19 - 0
components/esp_http_server/src/httpd_ws.c

@@ -482,6 +482,25 @@ esp_err_t httpd_ws_get_frame_type(httpd_req_t *req)
         /* Now turn the frame to PONG */
         /* Now turn the frame to PONG */
         frame.type = HTTPD_WS_TYPE_PONG;
         frame.type = HTTPD_WS_TYPE_PONG;
         return httpd_ws_send_frame(req, &frame);
         return httpd_ws_send_frame(req, &frame);
+    } else if (aux->ws_type == HTTPD_WS_TYPE_CLOSE) {
+        ESP_LOGD(TAG, LOG_FMT("Got a WS CLOSE frame, Replying CLOSE..."));
+
+        /* Read the rest of the CLOSE frame and response */
+        /* Please refer to RFC6455 Section 5.5.1 for more details */
+        httpd_ws_frame_t frame;
+        uint8_t frame_buf[128] = { 0 };
+        memset(&frame, 0, sizeof(httpd_ws_frame_t));
+        frame.payload = frame_buf;
+
+        if (httpd_ws_recv_frame(req, &frame, 126) != ESP_OK) {
+            ESP_LOGD(TAG, LOG_FMT("Cannot receive the full CLOSE frame"));
+            return ESP_ERR_INVALID_STATE;
+        }
+
+        frame.len = 0;
+        frame.type = HTTPD_WS_TYPE_CLOSE;
+        frame.payload = NULL;
+        return httpd_ws_send_frame(req, &frame);
     }
     }
 
 
     return ESP_OK;
     return ESP_OK;