ESP32 Websocket Server

Baldhead
Posts: 443
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32 Websocket Server

Postby Baldhead » Wed Aug 05, 2020 4:30 pm

No one to help ???!!!!

stdenits
Posts: 23
Joined: Sun May 17, 2020 3:18 pm

Re: ESP32 Websocket Server

Postby stdenits » Thu Aug 06, 2020 3:56 am

Baldhead wrote:
Wed Aug 05, 2020 7:59 am
Note: I can already send a message(same message) to all connected clients, but after the websocket are open(ie: finished websocket handshake i think).
Hi.

Can you do this asynchronously?

I want to send a message to the ws-client from the main loop (int main ()), not from the ws-handler; and one ws-connection just fine for me.

My problem is that I can't even get the ws-connection parameters (fs, hd) correctly and got the error:
W (64488) httpd_ws: httpd_ws_get_frame_type: Failed to read header byte (socket FD invalid), closing socket now
Could you please share the code to save the parameters of the current ws-connection?

Baldhead
Posts: 443
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32 Websocket Server

Postby Baldhead » Thu Aug 06, 2020 4:29 am

Hi,

I would like to know if it's possible set two uri's of type websocket inside "esp32 websocket server", but with a client using only a single socket to access both uri's.

I tried to write a javascript test code inside the web browser, but opened 2 sockets(1 socket for each uri).
I think because i create two new WebSocket(xxx uri) objects.
I dont know if i can send requests with different uri's in only a new WebSocket(xxx uri) object.

Javascript partial code:

Code: Select all

var wsUri = "ws://192.168.0.9/";				
			
var wsStateUri = "ws://192.168.0.9/serverState";

websocket = new WebSocket(wsUri);

websocketState = new WebSocket(wsStateUri);
I want to do 2 websockets requests(with different uri) using only a single socket if this is possible.

"Esp32 websocket server" partial code:

Code: Select all

     // URI handler for websocket client(s) message reception.
    httpd_uri_t get_clients_message = {
        .uri       = "/",  
        .method    = HTTP_GET,
        .handler   = get_clients_message_handler,
        .user_ctx  = NULL,
        .is_websocket = true
    };
    httpd_register_uri_handler(server, &get_clients_message);
    
     
    // URI handler for websocket client(s) get server state.
    httpd_uri_t get_server_state = {
        .uri       = "/serverState",  
        .method    = HTTP_GET,
        .handler   = get_server_state_handler,  
        .user_ctx  = NULL,
        .is_websocket = true
    };
    httpd_register_uri_handler(server, &get_server_state);   

Thank's.

Baldhead
Posts: 443
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32 Websocket Server

Postby Baldhead » Thu Aug 06, 2020 5:02 am

stdenits wrote:
Thu Aug 06, 2020 3:56 am
Baldhead wrote:
Wed Aug 05, 2020 7:59 am
Note: I can already send a message(same message) to all connected clients, but after the websocket are open(ie: finished websocket handshake i think).
Hi.

Can you do this asynchronously?

I want to send a message to the ws-client from the main loop (int main ()), not from the ws-handler; and one ws-connection just fine for me.

My problem is that I can't even get the ws-connection parameters (fs, hd) correctly and got the error:
W (64488) httpd_ws: httpd_ws_get_frame_type: Failed to read header byte (socket FD invalid), closing socket now
Could you please share the code to save the parameters of the current ws-connection?
Hi,

"Can you do this asynchronously?"
Yes.

Declaring global variable to facilitate.
static httpd_handle_t server = NULL;
httpd_start(&server, &config)

I am using this function:
esp_err_t httpd_queue_work(httpd_handle_t handle, httpd_work_fn_t work, void *arg)
esp_err_t httpd_queue_work( server, ws_async_message_send, &sockfd)

static void ws_async_message_send(void *arg)
{
int* fd = (int*)arg;

printf("*fd = %d\n\n", *fd );

httpd_ws_send_frame_async(server, *fd, &ws_pkt);
// configure packet(ws_pkt) before. all four struct parameters correctly.
// declare global variable: "static httpd_ws_frame_t ws_pkt;"
// declare global variable: buffer "buf" to "ws_pkt.payload = buf" too to facilitate.
// work with global variables facilitate because local variable are destroyed and this may be your problem.
// the socket list are global too.
}


I registered two functions in httpd_config_t before start the server.

config.open_fn = opened_socket_handler;
config.close_fn = closed_socket_handler;

When the socket open the callback function "opened_socket_handler" are called.
Callback function prototype: typedef esp_err_t (*httpd_open_func_t)(httpd_handle_t hd, int sockfd);

When the socket close the callback function "closed_socket_handler" are called.
Callback function prototype: typedef void (*httpd_close_func_t)(httpd_handle_t hd, int sockfd);

These 2 callback function pass a parameter " int sockfd".

I created a global variable "list" to insert in the list the socket when the open function are called.
and delete the socket from the list when the close function are called.

Be careful with your websocket client side. See if the client are not opening more than one single socket per client. This can get you in trouble.

Websocket rfc is helpful too to understand the packet format and other things:
https://tools.ietf.org/html/rfc6455

geo6555
Posts: 1
Joined: Tue Feb 23, 2021 9:37 am

Re: ESP32 Websocket Server

Postby geo6555 » Tue Feb 23, 2021 9:40 am

Hello, i am late, but can you attach a representation of the code you mentioned above ?

abansal22
Posts: 105
Joined: Wed Apr 22, 2020 8:24 am

Re: ESP32 Websocket Server

Postby abansal22 » Sun Aug 15, 2021 1:53 pm

Baldhead wrote:
Thu Aug 06, 2020 5:02 am
stdenits wrote:
Thu Aug 06, 2020 3:56 am
Baldhead wrote:
Wed Aug 05, 2020 7:59 am
Note: I can already send a message(same message) to all connected clients, but after the websocket are open(ie: finished websocket handshake i think).
Hi.

Can you do this asynchronously?

I want to send a message to the ws-client from the main loop (int main ()), not from the ws-handler; and one ws-connection just fine for me.

My problem is that I can't even get the ws-connection parameters (fs, hd) correctly and got the error:
W (64488) httpd_ws: httpd_ws_get_frame_type: Failed to read header byte (socket FD invalid), closing socket now
Could you please share the code to save the parameters of the current ws-connection?
Hi,

"Can you do this asynchronously?"
Yes.

Declaring global variable to facilitate.
static httpd_handle_t server = NULL;
httpd_start(&server, &config)

I am using this function:
esp_err_t httpd_queue_work(httpd_handle_t handle, httpd_work_fn_t work, void *arg)
esp_err_t httpd_queue_work( server, ws_async_message_send, &sockfd)

static void ws_async_message_send(void *arg)
{
int* fd = (int*)arg;

printf("*fd = %d\n\n", *fd );

httpd_ws_send_frame_async(server, *fd, &ws_pkt);
// configure packet(ws_pkt) before. all four struct parameters correctly.
// declare global variable: "static httpd_ws_frame_t ws_pkt;"
// declare global variable: buffer "buf" to "ws_pkt.payload = buf" too to facilitate.
// work with global variables facilitate because local variable are destroyed and this may be your problem.
// the socket list are global too.
}


I registered two functions in httpd_config_t before start the server.

config.open_fn = opened_socket_handler;
config.close_fn = closed_socket_handler;

When the socket open the callback function "opened_socket_handler" are called.
Callback function prototype: typedef esp_err_t (*httpd_open_func_t)(httpd_handle_t hd, int sockfd);

When the socket close the callback function "closed_socket_handler" are called.
Callback function prototype: typedef void (*httpd_close_func_t)(httpd_handle_t hd, int sockfd);

These 2 callback function pass a parameter " int sockfd".

I created a global variable "list" to insert in the list the socket when the open function are called.
and delete the socket from the list when the close function are called.

Be careful with your websocket client side. See if the client are not opening more than one single socket per client. This can get you in trouble.

Websocket rfc is helpful too to understand the packet format and other things:
https://tools.ietf.org/html/rfc6455
Thanks baldhead. I appreciate your good work. It help a lot!

Baldhead
Posts: 443
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32 Websocket Server

Postby Baldhead » Fri Aug 20, 2021 8:41 pm

Thank's for the compliment @abansal22

Who is online

Users browsing this forum: No registered users and 74 guests