Is this normal behavior? Chrome client is connected to the ESP's httpd server through a websocket.
When I receive a packet on the ESP, if I only respond with httpd_ws_send_frame() the browser receives the reply immediately. But if I send a response then trigger an async send like in the example, the client receives both packets at the same time. Like the first packet is delayed until the work function has been called, even if the work function takes several seconds to execute. If I insert a small 20ms delay between httpd_ws_send_frame() and the trigger_async_send() then I correctly receive the first message before the second but it's flaky and doesn't seem reliable, beside being ugly. I don't want to insert delays everywhere.
I tried sending the response before and after calling trigger_async send. I set the httpd server priority to 3. I tried setting the TCP_NODELAY socket option and so far nothing works although I'm not entirely sure I'm setting the TCP_NODELAY option correctly even if setsockopt() returns 0. As soon as I do both send a response and trigger an async send, the first response is delayed.
Any thoughts? I'm thinking of just using multiple async_send when I have to send data more than once for a single request and use the httpd_ws_send_frame() 'normal reply' only when I have to send data only once for a request. But I would prefer to do what seems logic, i.e. sending a response to a request and then asynchronously sending the remainder of the response when it's ready.
4.3 server websocket - send_frame delayed when using async_send
-
- Posts: 11
- Joined: Sun Aug 23, 2020 12:20 am
-
- Posts: 69
- Joined: Thu Nov 01, 2018 8:32 am
Re: 4.3 server websocket - send_frame delayed when using async_send
Hi Justin2020,
Yes, this is the expected behaviour. The reason for that is that both `httpd_ws_send_frame()` and `httpd_queue_work()` are executed from the same thread, and in addition to that (since the example runs these functions directly from the httpd handlers) this is also the httpd main thread, so whenever httpd gets to sending the data to network both of the above requests are already queued in.
In case you wanted the async messages to be sent later, you might call `httpd_queue_work()` from a separate thread (with a lower priority than httpd main thread).
Yes, this is the expected behaviour. The reason for that is that both `httpd_ws_send_frame()` and `httpd_queue_work()` are executed from the same thread, and in addition to that (since the example runs these functions directly from the httpd handlers) this is also the httpd main thread, so whenever httpd gets to sending the data to network both of the above requests are already queued in.
In case you wanted the async messages to be sent later, you might call `httpd_queue_work()` from a separate thread (with a lower priority than httpd main thread).
-
- Posts: 11
- Joined: Sun Aug 23, 2020 12:20 am
Re: 4.3 server websocket - send_frame delayed when using async_send
Thank for the reply. I put the async_send in a queue and task of its own and it didn't help. I gave the httpd server a priority of 3 and a priority of 8 for the async_send task. I included a screenshot of the piece of code where it happens. As you can see, I respond with httpd_ws_send_frame() then create an event, free the memory and exit the function.
At this point, there is still no work load created and the response have been queued. In the task, I launch the scan and only once it's completed do I create the work order and that happens over two seconds after calling httpd_ws_send_frame(). And only when sending the scan results does the first response finally get sent.
I have other web requests that doesn't trigger a work order and the reply is sent instantaneously. With all my trials & errors, I found that as soon as I create an event with xQueueSendToBack, the initial response doesn't get sent.
This shot is the scan request. As you can see the send_frame is called before the queue event is created. And in the task shot here you can see that the work load is only created once the scan is completed. Even then, the first response is only sent at the same time as the scan results. I added debug messages (now removed) and I exit the request handler long before the scan completes.
At this point, there is still no work load created and the response have been queued. In the task, I launch the scan and only once it's completed do I create the work order and that happens over two seconds after calling httpd_ws_send_frame(). And only when sending the scan results does the first response finally get sent.
I have other web requests that doesn't trigger a work order and the reply is sent instantaneously. With all my trials & errors, I found that as soon as I create an event with xQueueSendToBack, the initial response doesn't get sent.
This shot is the scan request. As you can see the send_frame is called before the queue event is created. And in the task shot here you can see that the work load is only created once the scan is completed. Even then, the first response is only sent at the same time as the scan results. I added debug messages (now removed) and I exit the request handler long before the scan completes.
-
- Posts: 11
- Joined: Sun Aug 23, 2020 12:20 am
Re: 4.3 server websocket - send_frame delayed when using async_send
Editing post. It wasn't really a problem. I was trying to have a packet sent when the wifi was busy scanning, a.k.a programmer snafu.
Still a lesson learned. Good work on esp-idf. Loving it!
Still a lesson learned. Good work on esp-idf. Loving it!
Who is online
Users browsing this forum: jcolebaker and 169 guests