Getting and error using httpd_ws_send_frame_async ??
Posted: Wed May 10, 2023 8:37 am
Hello, i am runing a httpserver from a ESP32-S3, overal the functionallity is there.
i have a task where i call a async send with some service information like uptime, version but also some data changing with 25 hz.
The webserver can run for sometimes 1 hour, but sudddenly i get an error on :
It sometimes returns -1, for a while and then crashes. I dont know how to errorhandle it, because i try to get the newest client list, so if a client isnt availible i would think im not trying to send to it.
This is the task :
This is the async sender:
i have a task where i call a async send with some service information like uptime, version but also some data changing with 25 hz.
The webserver can run for sometimes 1 hour, but sudddenly i get an error on :
Code: Select all
esp_err_t err = httpd_ws_send_frame_async(hd, fd, &ws_pkt);
This is the task :
Code: Select all
void homePage_task(void *pvParameters) {
list_spiffs_files();
// Allocate memory for resp_arg1
resp_arg1 = malloc(sizeof(struct async_resp_arg));
if (resp_arg1 == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory for resp_arg1");
vTaskDelete(NULL);
}
resp_arg1->hd = server; // server is the HTTP server handle
while (1) {
uint32_t t = esp_timer_get_time() / 1000;
size_t fds = max_clients;
int client_fds[max_clients];
esp_err_t ret = httpd_get_client_list(server, &fds, client_fds);
if (ret != ESP_OK) {
continue;
}
// Send data to each active WebSocket client
for (int i = 0; i < fds; i++) {
int client_info = httpd_ws_get_fd_info(server, client_fds[i]);
if (client_info == HTTPD_WS_CLIENT_WEBSOCKET) {
struct async_resp_arg* resp_arg = (struct async_resp_arg*)malloc(sizeof(struct async_resp_arg));
if (resp_arg == NULL) {
ESP_LOGE(TAG, "Error allocating memory for resp_arg");
continue;
}
resp_arg->hd = server;
resp_arg->fd = client_fds[i];
esp_err_t err = ws_async_send_struct(resp_arg, &msg);
if(err != ESP_OK){
}
}
}
// Wait for some time before sending the next data
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
Code: Select all
void send_websocket_message(void *arg) {
struct async_resp_arg *resp_arg = arg;
httpd_handle_t hd = resp_arg->hd;
int fd = resp_arg->fd;
httpd_ws_frame_t ws_pkt;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.payload = (uint8_t *)resp_arg->data;
ws_pkt.len = resp_arg->len;
ws_pkt.type = HTTPD_WS_TYPE_BINARY;
ws_pkt.final = true;
ws_pkt.fragmented = false;
esp_err_t err = httpd_ws_send_frame_async(hd, fd, &ws_pkt);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error sending WebSocket frame: %d", err);
close(resp_arg->fd);
}
free(resp_arg->data);
free(resp_arg);
}
Code: Select all
esp_err_t ws_async_send_struct(void *arg, const WebSocketMessage_t* msg) {
struct async_resp_arg *resp_arg = malloc(sizeof(struct async_resp_arg));
resp_arg->hd = ((struct async_resp_arg *)arg)->hd;
resp_arg->fd = ((struct async_resp_arg *)arg)->fd;
resp_arg->data = malloc(sizeof(WebSocketMessage_t));
memcpy(resp_arg->data, msg, sizeof(WebSocketMessage_t));
resp_arg->len = sizeof(WebSocketMessage_t);
esp_err_t err = httpd_queue_work(resp_arg->hd, send_websocket_message, resp_arg);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error scheduling WebSocket send work: %d", err);
free(resp_arg->data);
free(resp_arg);
return err;
}
return ESP_OK;
}