-
Notifications
You must be signed in to change notification settings - Fork 7.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issues with mdns server and now with websocket server too (IDFGH-5259) #7027
Comments
Hi @baldhead69 Could you please share more details:
The above warnings tell us, that an error occurred during tcp receive, enabling debug log would tell us, what kind of error it was (probably some kind of disconnection). Or maybe there already was an error on the ESP_LOGW(TAG, LOG_FMT("error in %s : %d"), ctx, errno); Cannot help much without more information, as now this looks to me like you've changed your network configuration, your project stopped working, so you switched to If your project is based on some of the |
Hi @david-cermak , I already uninstalled the v4.4-dev-1254-g639e7ad49. I dont switch the esp-idf versions on my computer. |
Hi @david-cermak , Follow the attached responses:
|
With the little info you've provided, we could only guess that the TLS handshake completed successfully and you're getting corrupted received data. No idea about the application, so assuming that you've registered a Listing the commits between v4.2.1...v4.4-dev-1254 I would fortune my guess to this one:
Now the uri handler gets called immediately after the handshake. In the handler we can identify that this was the handshake by checking req->method as it is still a GET from the first part of the handshake the client has sent. On a normal websocket-frame-receive (when normally a websocket uriHandler gets called) this field is set to 0 Closes #6597 Could you please try to check for the static esp_err_t ws_handler(httpd_req_t *req)
{
+ if (req->method == HTTP_GET) {
+ ESP_LOGI(TAG, "Handshake done, the new connection was opened");
+ return ESP_OK;
+ }
...
} |
Hi @david-cermak, I dont have v4.4-dev-1254-g639e7ad49 installed anymore in my computer, only v4.2.1. In v4.2.1 the websocket are working "perfectly" and in v4.4-dev-1254-g639e7ad49 the data was corrupted. I dont change my cell phone app with both versions of esp-idf tests, so i suppose the bug is in the version v4.4-dev-1254-g639e7ad49. I had the two problems in v4.4-dev-1254-g639e7ad49: and corruped data in websocket payload too. |
Yes, there could indeed be a bug in the latest IDF, but to find it, we would need your help. We have many applications which work perfectly on the latest |
@baldhead69 Thanks for reporting. Would you please help share if any updates for this issue? Thanks. |
@baldhead69 Thanks for reporting. Would you please help share if any updates for this issue? Thanks. |
Hi @Alvin1Zhang , Apparently all is working in v4.2.1 and not working in version v4.4-dev-1254-g639e7ad49. When will esp32-s3 be made available to the general public ? Could you provide me with samples of development boards with esp32-s3 ? Thank's. |
@baldhead69 Could you please share more details and a small portion of your application code to reproduce the issue as asked in #7027 (comment) ? |
Thanks for reporting and sorry for late reply, regarding ESP32-S3 sample boards, please contact https://www.espressif.com/en/contact-us/get-samples, thanks. |
Hi @Alvin1Zhang , I send a "sales questions". Thank's. |
@baldhead69 Could you please share more details on this issue? The title says:
but no mdns problem has been reported and the websocket server seems to work correctly on my end. |
Hi @david-cermak , What you need ? Full project ? I can sent to a private email. |
@baldhead69 Just the piece of code that sets the https server up in websocket mode, if that's enough to reproduce the problem. I'd believe it would be about 20 lines of code calling the http-server API. This could be shared here. It would be also great to remove the
That might be helpful, too, but let's try with the snippet first. If you're willing to share the project via email, you can send it to my git address (present in any of my commits ), e.g.: cd esp-idf
git fetch
git show dbbf21 | grep Author |
|
@baldhead69 Thanks for sharing the code. I've been testing it and found no issues. But I used this *very simple handler as your static esp_err_t get_clients_message_handler(httpd_req_t *req)
{
if (req->method == HTTP_GET) {
ESP_LOGI(TAG, "Handshake done, the new connection was opened");
return ESP_OK;
}
httpd_ws_frame_t ws_pkt;
uint8_t *buf = NULL;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
// First receive the full ws message
/* Set max_len = 0 to get the frame len */
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, 0);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_recv_frame failed to get frame len with %d", ret);
return ret;
}
ESP_LOGI(TAG, "frame len is %d", ws_pkt.len);
if (ws_pkt.len) {
/* ws_pkt.len + 1 is for NULL termination as we are expecting a string */
buf = calloc(1, ws_pkt.len + 1);
if (buf == NULL) {
ESP_LOGE(TAG, "Failed to calloc memory for buf");
return ESP_ERR_NO_MEM;
}
ws_pkt.payload = buf;
/* Set max_len = ws_pkt.len to get the frame payload */
ret = httpd_ws_recv_frame(req, &ws_pkt, ws_pkt.len);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_recv_frame failed with %d", ret);
free(buf);
return ret;
}
}
if (ws_pkt.type == HTTPD_WS_TYPE_TEXT) {
ESP_LOGI(TAG, "Received packet with message: %s", ws_pkt.payload);
ret = httpd_ws_send_frame(req, &ws_pkt);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_send_frame failed with %d", ret);
}
ESP_LOGI(TAG, "ws_handler: httpd_handle_t=%p, sockfd=%d, client_info:%d", req->handle,
httpd_req_to_sockfd(req), httpd_ws_get_fd_info(req->handle, httpd_req_to_sockfd(req)));
free(buf);
return ret;
}
free(buf);
return ESP_OK;
} Could you please share your ws handler, too? How do you use the |
Hi @david-cermak , I sent you an email. |
Hi @david-cermak , The mdns stop of sending multicast packets after some time after esp32 turning on(some hours). Edit: Do you have a open source robust wifi config to me use in esp32 ? Thank's. |
Hi @baldhead69 Thanks for sharing the project. I've made it compilable supplying some missing symbols (like the list of clients and the array of function pointers). And was able to reproduce an issue (not sure though if that was the issue you reported). static esp_err_t get_clients_message_handler(httpd_req_t *req)
{
+ ws_pkt.payload = buf;
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, sizeof(buf)); // sizeof(buf) = 128 bytes
if (ret != ESP_OK)
{
#if webSocketDebug
printf( "\nhttpd_ws_recv_frame failed with: %d code.\n", ret );
#endif
return ret;
} After this change the project seemed to work correctly, didn't run the custom functions, but got the expected reply over ws transport: As mentioned earlier, there might be some minor inconsistencies of using the ws api between releases, but this was actually present on Just a note, that if I understand your project correctly, you're implementing manually what has been implemented in this example on https://github.com/espressif/esp-idf/tree/release/v4.3/examples/protocols/https_server/wss_server As for the mdns, we've been reported an issue with avahi #7124 causing the mdns library to stop responding (only with avahi and only after the TTL expires), but this is fixed already and backported to all release branches. |
I don't think you reproduced the problem correctly. The "ws_pkt.payload = buf;" i initialize into another function. |
With regards to Mdns, i checked again that esp32 was not sending the multicast packet to the network and i checked in the router list that esp32 was connected. |
I installed de esp-idf version: v4.4-dev-2359-g58022f859, and the websocket bug yet exist.
|
Some suggestion ???? |
@baldhead69 Thanks for sharing updates, sorry for replying late, we are still investigate this issue, will update once we have any progress. Thanks. |
Remove rather than disable, but we already did this exercise and found no issue. These kind of problems are very hard to find and decide whether the culprit is the user part or the IDF part. Therefore we usually ask users to provide a minimal, reproducible example (i believe I asked for that in the very first reply).
This is weird, but very unlikely has any connection to the issue you're reporting. Is it the http server which takes that long to start? Checked the code you shared and didn't see any such delay.
I haven't noticed any received data when the connection stayed open with no data sent when testing your project. The wireshark log should reveal if any data are coming or not. Might your clients pinging the server, perhaps? As mentioned above, we still wanted to follow these three points:
Of course (repeating myself again), a minimal reproducible example would be very helpful |
In my android app i disabled the ping to test.
I just need to test with the wifi initialization implemented in esp-idf examples. |
Today i tested with ESP32-PICO-DevKitM-2 board and the problem persists. |
I sent "a minimal reproducible example code" to your email. Even me using the wifi example code from esp-idf the problem persists. I used the hotspot of my notebook too, created by windows to eliminate the access point variable and the problem persists. |
@baldhead69 Thanks for sharing the project! Finally, I was able to reproduce the issue! The problem is that the ws handler is also called upon http-get method, so that we misread the second byte of the WS protocol manually in the handler and read the first one instead. That's why the packet types and lengths were wrong.
You can fix it in your code adding this condition: in your handler. Sorry I haven't noticed you're also missing this condition in the first version you supplied, but that was largely incomplete so I filled the missing parts myself. Also, please re-read my second post in this issue back from May where I guessed that this had been the very problem! |
I think this new feature is bad( commit a1d5cfc ). My suggestion is much better, however, the espressif team never wanted to apply it. I think that when the server call the uri handler for the first time, the handshake is already finished, am I right ? "Thanks baldhead. I appreciate your good work. It help a lot!" I opened this feature request a 3 days ago, but i've been asking for this solution for a long time(more than one year) and i think my idea also solves the issue #6597 besides my idea being a lot less workaround. My feature request: #7431
I tested the proposed "solution". With local variables the "solution" works. static esp_err_t get_clients_message_handler(httpd_req_t *req)
{
httpd_ws_frame_t pkt;
uint8_t bu[128] = { 0 };
memset(&pkt, 0, sizeof(httpd_ws_frame_t));
pkt.payload = bu;
} With static global variables the "solution" dont works. static uint8_t buf[128] = { 0 };
static httpd_ws_frame_t ws_pkt;
static uint8_t state_buf[128] = { 0 };
static httpd_ws_frame_t ws_server_state_pkt;
static void init_frame_variables()
{
// Receiver and transmitter frame
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.payload = buf;
// Transmitter only frame
memset(&ws_server_state_pkt, 0, sizeof(httpd_ws_frame_t));
ws_server_state_pkt.payload = state_buf;
ws_server_state_pkt.final = true;
ws_server_state_pkt.type = HTTPD_WS_TYPE_BINARY;
} Why the first call to uri handler(when websocket client open connection) are of type "req->method == HTTP_GET" ? Why the other calls to uri handler are of type "req->method == HTTP_DELETE" ? |
Hi @baldhead69 Here's the complete diff of your project to make it working diff -u components/communication/my_wss_server/src/webSocket_server.c
@@ -122,6 +122,11 @@
return ESP_OK;
*/
+ if (req->method == HTTP_GET) {
+ return ESP_OK;
+ }
+ ws_pkt.payload = buf;
+ ws_pkt.len = 0;
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, sizeof(buf)); // sizeof(buf) = 128 bytes As for the feature requests, they are evaluated by component owner's team based on customer requests, if we have more customers, more likely the feature will be implemented (You know my opinion (and reasoning) on your suggestion of calling I have to admit, though, that the changes to cause your problems are breaking and |
Hi @david-cermak , So i assume this approach is correct for adding a websocket client to a list, right ? At the beginning of uri handler:
if( req->method == HTTP_GET )
{
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake done, the new connection was opened"));
int sockfd = httpd_req_to_sockfd(req);
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake Socket: %d"), sockfd);
add_ws_client_to_list(sockfd);
printf("\n");
return ESP_OK;
} Here the closed socket it was supposed to be websocket("HTTPD_WS_CLIENT_WEBSOCKET"), but it is returning 1 // typedef void (*httpd_close_func_t)(httpd_handle_t hd, int sockfd);
static void closed_socket_handler(httpd_handle_t hd, int sockfd)
{
ESP_LOGI( WSS_SERVER_TAG, LOG_USER("Closed socket Function:") );
ESP_LOGI( WSS_SERVER_TAG, LOG_USER("hd = %p"), hd );
ESP_LOGI( WSS_SERVER_TAG, LOG_USER("Closed socket = %d"), sockfd );
// if( sockfd == websocket_Socket )
httpd_ws_client_info_t info = httpd_ws_get_fd_info(hd, sockfd);
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("info: %d"), info );
if( info != HTTPD_WS_CLIENT_WEBSOCKET )
return;
remove_ws_client_from_list(sockfd);
} |
@baldhead69 Unfortunately none of these is possible if you wanted to keep the list of ws clients only. I would suggest listing all clients and sorting the ws clients out only if any action (pinging, sending async messages) needed.
https://github.com/espressif/esp-idf/blob/master/components/esp_http_server/src/httpd_ws.c#L479 The latter is mostly true if your clients close the connection in a clean way (sending Please understand that the ws server support in IDF is very simple. It's not a full featured websocket server, just a httpd that understands ws frames and some of the heavy-lifting is left for the user code. |
Hi @david-cermak , I followed the example code"https://github.com/espressif/esp-idf/blob/master/examples/protocols/http_server/ws_echo_server/main/ws_echo_server.c". Partially code of function "static esp_err_t echo_handler(httpd_req_t *req)". The ws_pkt.len are returning buggy values. I (00:03:10.493) esp_https_server: performing session handshake
I (00:03:12.016) TAG: Handshake done, the new connection was opened
I (00:03:12.044) TAG: frame len is 1
I (00:03:15.503) TAG: frame len is 2
I (00:03:20.116) TAG: frame len is 5
I (00:03:20.118) TAG: frame len is 4
W (00:03:23.494) httpd_ws: httpd_ws_recv_frame: WS frame is not properly masked.
E (00:03:23.494) TAG: httpd_ws_recv_frame failed to get frame len with ESP_ERR_INVALID_STATE
I (00:03:23.500) WSS_SERVER: Closed socket handler: I am using binary frame "HTTPD_WS_TYPE_BINARY". static esp_err_t get_clients_message_handler(httpd_req_t *req)
{
if (req->method == HTTP_GET)
{
ESP_LOGI("TAG", "Handshake done, the new connection was opened");
return ESP_OK;
}
httpd_ws_frame_t ws_pkt;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
/* Set max_len = 0 to get the frame len */
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, 0);
if (ret != ESP_OK) {
ESP_LOGE("TAG", "httpd_ws_recv_frame failed to get frame len with %s", esp_err_to_name(ret));
return ret;
}
ESP_LOGI("TAG", "frame len is %d", ws_pkt.len);
return ESP_OK;
} |
As a suggestion could have a function that returns the payload size directly like for example: static esp_err_t websocket_uri_handler( httpd_req_t *req )
{
if (req->method == HTTP_GET)
{
ESP_LOGI("TAG", "Handshake done, the new connection was opened");
return ESP_OK;
}
size_t payload_size = httpd_ws_get_payload_size(req);
} |
@baldhead69 The original API works good, but you have to read the payload after checking the length. The same way it's outlined in the example. Otherwise next payload check reads the actual payload data from the network and reads incorrectly. // read length
httpd_ws_recv_frame(req, &ws_pkt, 0);
// log length
ESP_LOGI( WSS_SERVER_TAG, LOG_USER("length: %d"), ws_pkt.len );
// read payload
httpd_ws_recv_frame(req, &ws_pkt, ws_pkt.len); // provided sizeof(buf) > ws_pkt.len |
Except the first payload packet that has payload lenght 1 the rest of the payloads lenght is 4. |
Hi @baldhead69 I wonder if you're really asking support questions or just randomly shuffle the lines in your handler to post a log proving that it doesn't work. About your query on the binary frames and "The ws_pkt.len returning buggy values" : diff -u components/communication/my_wss_server/src/webSocket_server.c
@@ -73,8 +73,6 @@
ESP_LOGE("TAG", "httpd_ws_recv_frame failed to get frame len with %s", esp_err_to_name(ret));
return ret;
}
- ws_pkt.payload = buf;
- httpd_ws_recv_frame(req, &ws_pkt, sizeof(buf));
ESP_LOGI("TAG", "frame len is %d", ws_pkt.len);
return ESP_OK; As mentioned above, the websocket support in httpd is very simple and we have to read the data continuously in the user handler (need to read the payload and set the To my understanding, there are no issues with websocket server nor in mnds. |
I commented about the payload size because i decided to do some experiments (learning) with dynamic allocation of the httpd_ws_frame_t structure and payload buffer. I call a function that allocate the httpd_ws_frame_t and payload buffer and return a httpd_ws_frame_t pointer. The freed allocated memory show in example. Example: static esp_err_t get_clients_message_handler(httpd_req_t *req)
{
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("URI HANDLER:"));
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("req->method = %d\n"), req->method);
if( req->method == HTTP_GET )
{
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake done, the new connection was opened"));
int sockfd = httpd_req_to_sockfd(req);
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake Socket: %d\n"), sockfd);
return ESP_OK;
}
httpd_ws_frame_t ws_pkt;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
// Set max_len = 0 to get the frame len
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, 0);
if (ret != ESP_OK)
{
ESP_LOGE(WSS_SERVER_TAG, "httpd_ws_recv_frame failed to get frame len with: %s\n", esp_err_to_name(ret));
return ret;
}
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("frame len is: %d\n"), ws_pkt.len);
if( ws_pkt.len == 0 )
{
ESP_LOGE(WSS_SERVER_TAG, "ws_pkt.len == 0\n");
return ESP_FAIL;
}
// Does not exist.
// size_t payload_size = httpd_ws_recv_frame_payload_size(req);
// ret = allocate_ws_frame_memory(payload_size, &ws_frame_mem);
httpd_ws_frame_t* ws_frame_mem = NULL;
ret = allocate_ws_frame_memory(ws_pkt.len, &ws_frame_mem);
if( ret != ESP_OK )
{
ESP_LOGE(WSS_SERVER_TAG, "allocate_ws_frame_memory ERROR: %s\n", esp_err_to_name(ret));
return ret;
}
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("ws_frame_mem: %p"), ws_frame_mem);
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("ws_frame_mem->payload: %p\n"), ws_frame_mem->payload);
ret = free_ws_frame_memory( &ws_frame_mem );
if( ret != ESP_OK )
{
ESP_LOGE(WSS_SERVER_TAG, "free_ws_frame_memory ERROR: %s\n", esp_err_to_name(ret));
return ret;
}
return ESP_OK;
}
// This function is more interesting for sending packets than for receiving packets ?!
// inline maybe
static esp_err_t allocate_ws_frame_memory(size_t buf_size, httpd_ws_frame_t** allocated_ws_frame_memory)
{
if( buf_size == 0 )
return ESP_FAIL;
*allocated_ws_frame_memory = calloc(1, sizeof(httpd_ws_frame_t));
if(*allocated_ws_frame_memory == NULL)
return ESP_ERR_NO_MEM;
uint8_t* buf = calloc(buf_size, sizeof(uint8_t));
if (buf == NULL)
{
free(*allocated_ws_frame_memory);
return ESP_ERR_NO_MEM;
}
(*allocated_ws_frame_memory)->fragmented = false;
(*allocated_ws_frame_memory)->final = true;
(*allocated_ws_frame_memory)->payload = buf;
(*allocated_ws_frame_memory)->len = buf_size;
(*allocated_ws_frame_memory)->type = HTTPD_WS_TYPE_BINARY;
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("*allocated_ws_frame_memory: %p"), *allocated_ws_frame_memory);
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("buf: %p"), buf);
ESP_LOGI(WSS_SERVER_TAG, LOG_USER("(*allocated_ws_frame_memory)->payload: %p\n"), (*allocated_ws_frame_memory)->payload);
return ESP_OK;
}
static esp_err_t free_ws_frame_memory(httpd_ws_frame_t** allocated_ws_frame_memory)
{
if( (*allocated_ws_frame_memory == NULL) || (*allocated_ws_frame_memory)->payload == NULL )
return ESP_FAIL;
free( (*allocated_ws_frame_memory)->payload );
(*allocated_ws_frame_memory)->payload = NULL;
free( *allocated_ws_frame_memory );
*allocated_ws_frame_memory = NULL;
return ESP_OK;
} |
I discovered this option in "handle_ws_control_frames" in esp_http_server.h file. I enabled "handle_ws_control_frames" to receive PING frames from websockets clients. W (00:00:41.021) httpd_ws: httpd_ws_recv_frame: Failed to receive the second byte What am i doing wrong ? URI handler register: static const httpd_uri_t get_clients_message =
{
.uri = "/ws",
.method = HTTP_GET,
.handler = get_clients_message_handler,
.is_websocket = true,
.handle_ws_control_frames = true,
.user_ctx = NULL,
.supported_subprotocol = NULL
}; URI HANDLER: static uint8_t buf[64] = { 0 };
static httpd_ws_frame_t ws_pkt;
static esp_err_t get_clients_message_handler(httpd_req_t *req)
{
ESP_LOGI(WSS_SERVER_TAG, "URI HANDLER:");
ESP_LOGI(WSS_SERVER_TAG, "req->method = %d\n", req->method);
if( req->method == HTTP_GET )
{
ESP_LOGI(WSS_SERVER_TAG, "Handshake done, the new connection was opened");
int sockfd = httpd_req_to_sockfd(req);
ESP_LOGI(WSS_SERVER_TAG, "Handshake Socket: %d\n", sockfd);
return ESP_OK;
}
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.payload = buf;
// This function return ESP_FAIL.
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, sizeof(buf));
if( ret != ESP_OK )
{
ESP_LOGI(WSS_SERVER_TAG, "httpd_ws_recv_frame failed with: %s\n", esp_err_to_name(ret));
return ret;
}
if( ws_pkt.type == HTTPD_WS_TYPE_PING )
{
int sock = httpd_req_to_sockfd(req);
ESP_LOGI(WSS_SERVER_TAG, "HTTPD_WS_TYPE_PING: %d\n", sock);
return ESP_OK;
}
return ESP_OK;
} I tried the code below, based on "static esp_err_t ws_handler(httpd_req_t *req)" from "https://github.com/espressif/esp-idf/blob/master/examples/protocols/https_server/wss_server/main/wss_server_example.c", I (00:00:12.750) esp_https_server: performing session handshake
I (00:00:14.725) WSS_SERVER: Handshake done, the new connection was opened
W (00:00:44.871) httpd_ws: httpd_ws_recv_frame: Failed to receive the second byte
E (00:00:44.871) WSS_SERVER: httpd_ws_recv_frame failed to get frame len with -1 URI HANDLER CODE: static esp_err_t get_clients_message_handler(httpd_req_t *req)
{
if (req->method == HTTP_GET)
{
ESP_LOGI(WSS_SERVER_TAG, "Handshake done, the new connection was opened");
return ESP_OK;
}
httpd_ws_frame_t ws_pkt1;
uint8_t *buf = NULL;
memset(&ws_pkt1, 0, sizeof(httpd_ws_frame_t));
// First receive the full ws message
/* Set max_len = 0 to get the frame len */
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt1, 0);
if (ret != ESP_OK)
{
ESP_LOGE(WSS_SERVER_TAG, "httpd_ws_recv_frame failed to get frame len with %d", ret);
return ret;
}
ESP_LOGI(WSS_SERVER_TAG, "frame len is %d", ws_pkt1.len);
if (ws_pkt1.len)
{
/* ws_pkt.len + 1 is for NULL termination as we are expecting a string */
buf = calloc(1, ws_pkt1.len + 1);
if (buf == NULL)
{
ESP_LOGE(WSS_SERVER_TAG, "Failed to calloc memory for buf");
return ESP_ERR_NO_MEM;
}
ws_pkt1.payload = buf;
/* Set max_len = ws_pkt.len to get the frame payload */
ret = httpd_ws_recv_frame(req, &ws_pkt1, ws_pkt1.len);
if (ret != ESP_OK)
{
ESP_LOGE(WSS_SERVER_TAG, "httpd_ws_recv_frame failed with %d", ret);
free(buf);
return ret;
}
}
// If it was a PING
if (ws_pkt1.type == HTTPD_WS_TYPE_PING)
{
ESP_LOGD(WSS_SERVER_TAG, "Received PING message");
free(buf);
int sockfd = httpd_req_to_sockfd(req);
ESP_LOGI(WSS_SERVER_TAG, "SOCKFD: %d", sockfd);
return ESP_OK;
}
// If it was a BINARY message
else if (ws_pkt1.type == HTTPD_WS_TYPE_BINARY)
{
int sock = httpd_req_to_sockfd(req);
ESP_LOGI(WSS_SERVER_TAG, "HTTPD_WS_TYPE_BINARY: %d", sock);
free(buf);
return ESP_OK;
}
free(buf);
return ESP_OK;
} Maybe the problem is that the client ping has no message at all, ie, payload size is zero ?! I am using OKHTTP client library. |
Hi @david-cermak , Can you help me solve the question about ping ? The dynamic memory allocation for httpd_ws_frame_t and the payload buffer, at first i won't use. Thank's. |
I took two tests(using ws and not wss):
First test: Send ping with payload. The websocket ping control frame call uri handler: I (00:00:28.062) WSS_SERVER: Handshake done, the new connection was opened
I (00:00:28.070) WSS_SERVER: Handshake Socket: 55
I (00:00:28.162) WSS_SERVER: URI HANDLER:
I (00:00:28.166) WSS_SERVER: req->method = 0
W (00:00:28.172) httpd_txrx: httpd_sock_err: error in recv : 104
W (00:00:28.178) httpd_ws: httpd_ws_recv_frame: Failed to receive the second byte
I (00:00:28.186) WSS_SERVER: httpd_ws_recv_frame failed with: ESP_FAIL Second test: Send ping without payload. The websocket ping control frame call uri handler: I (00:00:57.224) WSS_SERVER: Handshake done, the new connection was opened
I (00:00:57.233) WSS_SERVER: Handshake Socket: 55
I (00:00:57.325) WSS_SERVER: URI HANDLER:
I (00:00:57.328) WSS_SERVER: req->method = 0
W (00:00:57.382) httpd_ws: httpd_ws_recv_frame: Failed to receive the second byte
I (00:00:57.382) WSS_SERVER: httpd_ws_recv_frame failed with: ESP_FAIL |
I already took the opportunity to test the websocket close control frame. The websocket close control frame dont call uri handler: I (00:00:23.257) WSS_SERVER: URI HANDLER:
I (00:00:23.258) WSS_SERVER: req->method = 1
I (00:00:23.258) WSS_SERVER: Handshake done, the new connection was opened
I (00:00:23.267) WSS_SERVER: Handshake Socket: 55
I (00:00:23.359) WSS_SERVER: Closed socket handler:
I (00:00:23.363) WSS_SERVER: hd = 0x3ffd5348
I (00:00:23.369) WSS_SERVER: Closed socket = 55 |
@baldhead69 Please be kind to us and create a separate issue for the control frames. We will close this one, once we update the docs. There might be some bugs in processing of ping frames with no payload, and passing the close frame to the handler. It is unrelated to this issue. |
OK, i will open a new issue.
There are some bugs in processing of ping frames with payload too. |
Hi,
My mdns server and websocket server were working properly for a long time.
I ended up putting the project aside for few months because i am waiting for the launch of the esp32-s3 modules.
When i came back to the project i decided to do some tests, and the mdns server was behaving strangely.
Using wireshark i saw that the mdns server sent the ad for about 6 times and stopped(after manual reset).
The first 4 times every 1 seconds and the last 2 times every 2 seconds and stopped.
I configured mdns on menuconfig so that it would send the notification to the network every 1 second.
During this period we moved to an new internet provider and also to a new wifi router.
I thought the problem could be the new wifi router, but i haven't been able to find the problem yet.
So i decided to update the esp-idf.
I updated to v4.4-dev-1254-g639e7ad49.
After esp-idf update the mdns problem still persists.
And now the websocket server also bugged.
Using the idf.py monitor, i can see that websocket server start ok, but when i connect to the server through my android application, the following message appears:
W (00:00:08.807) httpd_ws: httpd_ws_get_frame_type: Failed to read header byte (socket FD invalid), closing socket now
W (00:00:08.816) httpd_ws: httpd_ws_get_frame_type: Failed to read header byte (socket FD invalid), closing socket now
Before the update of the esp idf, the websocket server worked ok, including "ESP-IDF Release v4.2.1".
Some suggestion on how to resolve the mdns server and now the websocket server bug ?
Note: i changed the httpd priority from "config.httpd.task_priority = tskIDLE_PRIORITY + 5" to "config.httpd.task_priority = configMAX_PRIORITIES".
@david-cermak
Thank's.
The text was updated successfully, but these errors were encountered: