Hello team!
I am working on a project where the client should be informed about a data update via a push from the server. The server is an ESP32 running esp_http_server and the data push is triggered by e.g., an SPI triggered event running in a seperate task.
What's the best way to accomplish this? All websocket examples (e.g., https://github.com/espressif/esp-idf/bl ... o_server.c) assume that the relevant code to trigger an update is called from within the request handler that is associated with the websocket (in particular regarding the access to the *req pointer).
To be able do something like [1], [2], it seems like I need access to the socket fds, that are associated with a previous websocket request as well as the httpd_handle_t that was initialized when the server was started. While I can pass the latter to other freertos task, I have no idea how to obtain the FDs in a nice manner and especially how to track whether they are related to a WS socket.
[1] https://github.com/espressif/esp-idf/bl ... rver.c#L40
[2] https://github.com/espressif/esp-idf/bl ... rver.c#L56
I have found the API function httpd_get_client_list() - is this the best way to accomplish this with manual tracking in the WS request handler which of those is related to a WS?
Thank you,
Tom
Websockets: Async send within an interrupt
Re: Websockets: Async send within an interrupt
I just found out that a lot of useful stuff (e.g. sock_db and its members ws_handshake_detect) can be retrieved from the struct
struct httpd_data
defined in esp_httpd_priv.h However it seems like this data is not meant to be accessed.
Any other way?
struct httpd_data
defined in esp_httpd_priv.h However it seems like this data is not meant to be accessed.
Any other way?
Re: Websockets: Async send within an interrupt
Hi guys!
Any ideas on this matter?
Best,
Tom
Any ideas on this matter?
Best,
Tom
Re: Websockets: Async send within an interrupt
I know this is old and likely solved for the OP, but thought I would offer help for anyone else working with websockets on the esp32.
I started down the same path with the example found at:
eps-idf/examples/protocols/http_server/ws_server
This was a good basic starting point.
A more complete example provided by espressif can be found at:
eps-idf/examples/protocols/https_server/wss_server
This example includes additional useful tools. For example registering a function for when a new client connects, when a client disconnects and provides for keep alive functionality.
Additionally it shows how to send to connected clients. Again, this example is much more complete than ws_server example. Here is the code where clients are accessed using only a handle to the server.
In this function, they do use the function httpd_get_client_list. A handle to the server is passed in and a pointer for size and client list. The size gets filled and the list as well which is the client_fds for each client.
Look at the rest of the example to see how the actual send happens after bing queued.
I started down the same path with the example found at:
eps-idf/examples/protocols/http_server/ws_server
This was a good basic starting point.
A more complete example provided by espressif can be found at:
eps-idf/examples/protocols/https_server/wss_server
This example includes additional useful tools. For example registering a function for when a new client connects, when a client disconnects and provides for keep alive functionality.
Additionally it shows how to send to connected clients. Again, this example is much more complete than ws_server example. Here is the code where clients are accessed using only a handle to the server.
- // Get all clients and send async message
- static void wss_server_send_messages(httpd_handle_t* server)
- {
- bool send_messages = true;
- // Send async message to all connected clients that use websocket protocol every 10 seconds
- while (send_messages) {
- vTaskDelay(10000 / portTICK_PERIOD_MS);
- if (!*server) { // httpd might not have been created by now
- continue;
- }
- size_t clients = max_clients;
- int client_fds[max_clients];
- if (httpd_get_client_list(*server, &clients, client_fds) == ESP_OK) {
- for (size_t i=0; i < clients; ++i) {
- int sock = client_fds[i];
- if (httpd_ws_get_fd_info(*server, sock) == HTTPD_WS_CLIENT_WEBSOCKET) {
- ESP_LOGI(TAG, "Active client (fd=%d) -> sending async message", sock);
- struct async_resp_arg *resp_arg = malloc(sizeof(struct async_resp_arg));
- resp_arg->hd = *server;
- resp_arg->fd = sock;
- if (httpd_queue_work(resp_arg->hd, send_hello, resp_arg) != ESP_OK) {
- ESP_LOGE(TAG, "httpd_queue_work failed!");
- send_messages = false;
- break;
- }
- }
- }
- } else {
- ESP_LOGE(TAG, "httpd_get_client_list failed!");
- return;
- }
- }
- }
Look at the rest of the example to see how the actual send happens after bing queued.
Who is online
Users browsing this forum: No registered users and 163 guests