我的想法是监听 HTTP_SERVER_EVENT_ON_CONNECTED 事件,用 xTaskCreate 创建一个任务,在任务里用 httpd_ws_send_frame_async 来发送数据,但遇到了一个问题:httpd_ws_get_fd_info 返回的总是 HTTP_WS_CLIENT_INVALID。我在任务内把传入的 fd 打印出来,发现任务里获取到的参数和我传入的 fd 的值不一样。
代码如下:
Code: Select all
#include "stdio.h"
#include "esp_log.h"
#include "esp_http_server.h"
#include "esp_event.h"
httpd_handle_t server = NULL;
httpd_ws_frame_t wsFrame = ...; // WebSocket 帧
void websocketSend(void* pvParameters) {
int fd = *((int *)pvParameters);
ESP_LOGI(TAG, "Task Created, fd = %d, pointer of pvParameters = %p", fd, pvParameters);
if(httpd_ws_get_fd_info(server, fd) == HTTPD_WS_CLIENT_WEBSOCKET) {
httpd_ws_send_frame_async(server, fd, &wsFrame);
}
}
void onHttpConnected(void* arg, esp_event_base_t eventBase, int32_t eventId, void* eventData) {
int *fd = (int *)eventData;
ESP_LOGI(TAG, "HTTP Connected, fd = %d, pointer = %p", *fd, fd);
task = xTaskCreate(websocketSend, "websocket", 4096, (void *)fd, 5, NULL);
}
esp_err_t ws_handler(httpd_req_t *req) {
if (req->method == HTTP_GET) {
ESP_LOGI(TAG, "Handshake done, the new connection was opened");
httpd_ws_send_frame_async(server, httpd_req_to_sockfd(req), &wsFrame);
return ESP_OK;
}
return ESP_OK;
}
void main() {
// Wi-Fi 连接部分省略
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_start(&server, &config);
httpd_uri_t websocket = {
.uri = "/ws",
.method = HTTP_GET,
.handler = ws_handler,
.user_ctx = NULL,
.is_websocket = true,
};
ESP_ERROR_CHECK(httpd_register_uri_handler(server, &websocket));
ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTP_SERVER_EVENT, HTTP_SERVER_EVENT_ON_CONNECTED, onHttpConnected, NULL));
}
Code: Select all
I (117268) TAG: HTTP Connected, fd = 57, pointer = 0x3fcb2790 // 在 event handler 中打印出的 fd 和地址
I (117278) TAG: Task Created, fd = 1070202036, pointer of pvParameters = 0x3fcb2790 // 在任务中打印出的传入的参数的值和地址,可以看到地址是一样的,但是值不一样
想请问一下这是为什么?我要怎么才能把 fd 正确传入任务里?