mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
esp_http_server: Add Websocket API to return list of active clients
Closes https://github.com/espressif/esp-idf/issues/5406
This commit is contained in:
@@ -409,6 +409,14 @@ typedef struct httpd_uri {
|
|||||||
#endif
|
#endif
|
||||||
} httpd_uri_t;
|
} httpd_uri_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure for holding list of clients
|
||||||
|
*/
|
||||||
|
typedef struct httpd_client_list {
|
||||||
|
size_t active_clients; /*!< number of active clients in this struct */
|
||||||
|
int client_fds[]; /*!< array of file descriptors of all active clients */
|
||||||
|
} httpd_client_list_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Registers a URI handler
|
* @brief Registers a URI handler
|
||||||
*
|
*
|
||||||
@@ -1466,6 +1474,19 @@ esp_err_t httpd_sess_trigger_close(httpd_handle_t handle, int sockfd);
|
|||||||
*/
|
*/
|
||||||
esp_err_t httpd_sess_update_lru_counter(httpd_handle_t handle, int sockfd);
|
esp_err_t httpd_sess_update_lru_counter(httpd_handle_t handle, int sockfd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns list of current socket descriptors of active sessions
|
||||||
|
*
|
||||||
|
* @param[in] handle Handle to server returned by httpd_start
|
||||||
|
* @param[in] max_fds Maximum number of socket fds the supplied list could hold
|
||||||
|
* @param[out] fd_list Structure holding socket descriptors
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK : Successfully retrieved session list
|
||||||
|
* - ESP_ERR_INVALID_ARG : Wrong arguments or list is longer than maximum
|
||||||
|
*/
|
||||||
|
esp_err_t httpd_get_client_list(httpd_handle_t handle, size_t max_fds, httpd_client_list_t *fd_list);
|
||||||
|
|
||||||
/** End of Session
|
/** End of Session
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
@@ -1526,6 +1547,15 @@ typedef enum {
|
|||||||
HTTPD_WS_TYPE_PONG = 0xA
|
HTTPD_WS_TYPE_PONG = 0xA
|
||||||
} httpd_ws_type_t;
|
} httpd_ws_type_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enum for client info description
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
HTTPD_WS_CLIENT_INVALID = 0x0,
|
||||||
|
HTTPD_WS_CLIENT_HTTP = 0x1,
|
||||||
|
HTTPD_WS_CLIENT_WEBSOCKET = 0x2,
|
||||||
|
} httpd_ws_client_info_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief WebSocket frame format
|
* @brief WebSocket frame format
|
||||||
*/
|
*/
|
||||||
@@ -1593,11 +1623,11 @@ esp_err_t httpd_ws_send_frame_async(httpd_handle_t hd, int fd, httpd_ws_frame_t
|
|||||||
* @param[in] hd Server instance data
|
* @param[in] hd Server instance data
|
||||||
* @param[in] fd Socket descriptor
|
* @param[in] fd Socket descriptor
|
||||||
* @return
|
* @return
|
||||||
* - -1 : This fd is not a client of this httpd
|
* - HTTPD_WS_CLIENT_INVALID : This fd is not a client of this httpd
|
||||||
* - 0 : This fd is an active client, protocol is not WS
|
* - HTTPD_WS_CLIENT_HTTP : This fd is an active client, protocol is not WS
|
||||||
* - 1 : This fd is an active client, protocol is WS
|
* - HTTPD_WS_CLIENT_WEBSOCKET : This fd is an active client, protocol is WS
|
||||||
*/
|
*/
|
||||||
int httpd_ws_get_fd_info(httpd_handle_t hd, int fd)
|
httpd_ws_client_info_t httpd_ws_get_fd_info(httpd_handle_t hd, int fd);
|
||||||
|
|
||||||
#endif /* CONFIG_HTTPD_WS_SUPPORT */
|
#endif /* CONFIG_HTTPD_WS_SUPPORT */
|
||||||
/** End of WebSocket related stuff
|
/** End of WebSocket related stuff
|
||||||
|
@@ -104,6 +104,25 @@ esp_err_t httpd_queue_work(httpd_handle_t handle, httpd_work_fn_t work, void *ar
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t httpd_get_client_list(httpd_handle_t handle, size_t max_fds, httpd_client_list_t *fd_list)
|
||||||
|
{
|
||||||
|
struct httpd_data *hd = (struct httpd_data *) handle;
|
||||||
|
if (hd == NULL || max_fds == 0 || fd_list == NULL || max_fds < hd->config.max_open_sockets) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
fd_list->active_clients = 0;
|
||||||
|
for (int i = 0; i < hd->config.max_open_sockets; ++i) {
|
||||||
|
if (hd->hd_sd[i].fd != -1) {
|
||||||
|
if (fd_list->active_clients < max_fds) {
|
||||||
|
fd_list->client_fds[fd_list->active_clients++] = hd->hd_sd[i].fd;
|
||||||
|
} else {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void *httpd_get_global_user_ctx(httpd_handle_t handle)
|
void *httpd_get_global_user_ctx(httpd_handle_t handle)
|
||||||
{
|
{
|
||||||
return ((struct httpd_data *)handle)->config.global_user_ctx;
|
return ((struct httpd_data *)handle)->config.global_user_ctx;
|
||||||
|
@@ -758,8 +758,8 @@ 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) {
|
||||||
ESP_LOGD(TAG, LOG_FMT("New WS request from existing socket"));
|
|
||||||
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);
|
||||||
|
|
||||||
/* Stop and return here immediately if it's a CLOSE frame */
|
/* Stop and return here immediately if it's a CLOSE frame */
|
||||||
if (ra->ws_type == HTTPD_WS_TYPE_CLOSE) {
|
if (ra->ws_type == HTTPD_WS_TYPE_CLOSE) {
|
||||||
@@ -767,13 +767,13 @@ esp_err_t httpd_req_new(struct httpd_data *hd, struct sock_db *sd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore PONG frame, as this is a server */
|
|
||||||
if (ra->ws_type == HTTPD_WS_TYPE_PONG) {
|
if (ra->ws_type == HTTPD_WS_TYPE_PONG) {
|
||||||
return ret;
|
/* Pass the PONG frames to the handler as well, as user app might send PINGs */
|
||||||
|
ESP_LOGD(TAG, LOG_FMT("Received PONG frame"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call handler if it's a non-control frame */
|
/* Call handler if it's a non-control frame */
|
||||||
if (ret == ESP_OK && ra->ws_type < HTTPD_WS_TYPE_CLOSE) {
|
if (ret == ESP_OK && ra->ws_type <= HTTPD_WS_TYPE_PONG) {
|
||||||
ret = sd->ws_handler(r);
|
ret = sd->ws_handler(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -383,15 +383,15 @@ esp_err_t httpd_ws_get_frame_type(httpd_req_t *req)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int httpd_ws_get_fd_info(httpd_handle_t hd, int fd)
|
httpd_ws_client_info_t httpd_ws_get_fd_info(httpd_handle_t hd, int fd)
|
||||||
{
|
{
|
||||||
struct sock_db *sess = httpd_sess_get(hd, fd);
|
struct sock_db *sess = httpd_sess_get(hd, fd);
|
||||||
|
|
||||||
if (sess == NULL) {
|
if (sess == NULL) {
|
||||||
return -1;
|
return HTTPD_WS_CLIENT_INVALID;
|
||||||
}
|
}
|
||||||
bool is_active_ws = sess->ws_handshake_done && (!sess->ws_close);
|
bool is_active_ws = sess->ws_handshake_done && (!sess->ws_close);
|
||||||
return is_active_ws ? 1 : 0;
|
return is_active_ws ? HTTPD_WS_CLIENT_WEBSOCKET : HTTPD_WS_CLIENT_HTTP;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_HTTPD_WS_SUPPORT */
|
#endif /* CONFIG_HTTPD_WS_SUPPORT */
|
||||||
|
Reference in New Issue
Block a user