Added more convenient functions for sending data to websocket

pull/7680/head
Martin Valik 2021-03-10 11:20:04 +01:00
rodzic 502e132e5d
commit 1f451a4a77
2 zmienionych plików z 121 dodań i 0 usunięć

Wyświetl plik

@ -1603,6 +1603,11 @@ typedef struct httpd_ws_frame {
size_t len; /*!< Length of the WebSocket data */
} httpd_ws_frame_t;
/**
* @brief Transfer complete callback
*/
typedef void (*transfer_complete_cb)(esp_err_t err, int socket, void *arg);
/**
* @brief Receive and parse a WebSocket frame
*
@ -1663,6 +1668,35 @@ esp_err_t httpd_ws_send_frame_async(httpd_handle_t hd, int fd, httpd_ws_frame_t
*/
httpd_ws_client_info_t httpd_ws_get_fd_info(httpd_handle_t hd, int fd);
/**
* @brief Sends data to to specified websocket synchronously
*
* @param[in] handle Server instance data
* @param[in] socket Socket descriptor
* @param[in] frame Websocket frame
* @return
* - ESP_OK : On successful
* - ESP_FAIL : When socket errors occurs
* - ESP_ERR_NO_MEM : Unable to allocate memory
*/
esp_err_t httpd_ws_send_data(httpd_handle_t handle, int socket, httpd_ws_frame_t *frame);
/**
* @brief Sends data to to specified websocket asynchronously
*
* @param[in] handle Server instance data
* @param[in] socket Socket descriptor
* @param[in] frame Websocket frame
* @param[in] callback Callback invoked after sending data
* @param[in] arg User data passed to provided callback
* @return
* - ESP_OK : On successful
* - ESP_FAIL : When socket errors occurs
* - ESP_ERR_NO_MEM : Unable to allocate memory
*/
esp_err_t httpd_ws_send_data_async(httpd_handle_t handle, int socket, httpd_ws_frame_t *frame,
transfer_complete_cb callback, void *arg);
#endif /* CONFIG_HTTPD_WS_SUPPORT */
/** End of WebSocket related stuff
* @}

Wyświetl plik

@ -16,9 +16,23 @@
#include <esp_http_server.h>
#include "esp_httpd_priv.h"
#include "freertos/event_groups.h"
#ifdef CONFIG_HTTPD_WS_SUPPORT
#define WS_SEND_OK (1 << 0)
#define WS_SEND_FAILED (1 << 1)
typedef struct {
httpd_ws_frame_t frame;
httpd_handle_t handle;
int socket;
transfer_complete_cb callback;
void *arg;
bool blocking;
EventGroupHandle_t transfer_done;
} async_transfer_t;
static const char *TAG="httpd_ws";
/*
@ -484,4 +498,77 @@ httpd_ws_client_info_t httpd_ws_get_fd_info(httpd_handle_t hd, int fd)
return is_active_ws ? HTTPD_WS_CLIENT_WEBSOCKET : HTTPD_WS_CLIENT_HTTP;
}
static void httpd_ws_send_cb(void *arg)
{
async_transfer_t *trans = arg;
esp_err_t err = httpd_ws_send_frame_async(trans->handle, trans->socket, &trans->frame);
if (trans->blocking) {
xEventGroupSetBits(trans->transfer_done, err ? WS_SEND_FAILED : WS_SEND_OK);
} else if (trans->callback) {
trans->callback(err, trans->socket, trans->arg);
}
free(trans);
}
esp_err_t httpd_ws_send_data(httpd_handle_t handle, int socket, httpd_ws_frame_t *frame)
{
async_transfer_t *transfer = calloc(1, sizeof(async_transfer_t));
if (transfer == NULL) {
return ESP_ERR_NO_MEM;
}
EventGroupHandle_t transfer_done = xEventGroupCreate();
if (!transfer_done) {
free(transfer);
return ESP_ERR_NO_MEM;
}
transfer->blocking = true;
transfer->handle = handle;
transfer->socket = socket;
transfer->transfer_done = transfer_done;
memcpy(&transfer->frame, frame, sizeof(httpd_ws_frame_t));
esp_err_t err = httpd_queue_work(handle, httpd_ws_send_cb, transfer);
if (err != ESP_OK) {
vEventGroupDelete(transfer_done);
free(transfer);
return err;
}
EventBits_t status = xEventGroupWaitBits(transfer_done, WS_SEND_OK | WS_SEND_FAILED,
pdTRUE, pdFALSE, portMAX_DELAY);
vEventGroupDelete(transfer_done);
return (status & WS_SEND_OK) ? ESP_OK : ESP_FAIL;
}
esp_err_t httpd_ws_send_data_async(httpd_handle_t handle, int socket, httpd_ws_frame_t *frame,
transfer_complete_cb callback, void *arg)
{
async_transfer_t *transfer = calloc(1, sizeof(async_transfer_t));
if (transfer == NULL) {
return ESP_ERR_NO_MEM;
}
transfer->arg = arg;
transfer->callback = callback;
transfer->handle = handle;
transfer->socket = socket;
memcpy(&transfer->frame, frame, sizeof(httpd_ws_frame_t));
esp_err_t err = httpd_queue_work(handle, httpd_ws_send_cb, transfer);
if (err) {
free(transfer);
return err;
}
return ESP_OK;
}
#endif /* CONFIG_HTTPD_WS_SUPPORT */