Page 1 of 1

Getting and error using httpd_ws_send_frame_async ??

Posted: Wed May 10, 2023 8:37 am
by mowglihaha
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 :

Code: Select all

esp_err_t err = httpd_ws_send_frame_async(hd, fd, &ws_pkt);
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 :

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

	}
}
This is the async sender:

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;
}

Re: Getting and error using httpd_ws_send_frame_async ??

Posted: Mon May 15, 2023 7:07 am
by MicroController
May or may not be related to the issue, but

Code: Select all

if (client_info == HTTPD_WS_CLIENT_WEBSOCKET) {
    struct async_resp_arg* resp_arg = (struct async_resp_arg*)malloc(sizeof(struct async_resp_arg));
That memory doesn't seem to be released anywhere.