curl_ws_send under multi_handle. Immediate send/blocking, or simply queues for curl_multi_perform/non-blocking? #18987
-
|
C++ Client using libcurl. After establishing a WebSocket under a multi_handle, beside other easy_handles to different endpoints on the same domain server, I call curl_ws_send to push a <1KB text packet out the WS pipe. (1) Does this go out immediately (in a blocking call that waits for a CURLE_OK to indicate actual reception on the other side, and ties up the client), or does this simply push the packet onto a "send" queue for the next curl_multi_perform to take care of (in a non-blocking call, in which case CURLE_OK would indicate "queued successfully")? Architecture and load: The same client WebSocket handles a rapid incoming stream of medium packets from the Server. ((After a curl_multi_info_read,) These get picked up from the multi_handle by a tight loop around curl_ws_recv as long as each gives CURLE_OK results, or half-filled and kept for next time around the run-loop if CURLE_AGAIN. So curl_multi_recv at least requires curl_multi_perform, and a loose [full run] loop around for CURLE_AGAIN cases.) And different easy_handles under the same multi_handle process sporadic REST requests, in a lazy-response non-blocking way. But the websocket.c example code only illustrates a single, blocking easy_handle without a multi_handle. It suggests a 1 sec wait if curl_ws_send returns CURLE_AGAIN. However, this is way too long for my live application. (2) Once a WebSocket has been set up, why would curl_ws_send ever return a CURLE_AGAIN code? And how likely is this for a <1000 bytes small packet? (3) In a remote client/server full-duplex connection over modern Internet ethernet, how likely is it that medium-heavy streaming incoming traffic would temporarily block outgoing WebSocket message packets on the same WebSocket? The whole idea of full-duplex is outgoing packets don't get blocked, no? And if not, isn't that what curl_multi_perform takes care of, under the hood? So I shouldn't expect to see any CURLE_AGAIN results on an outgoing curl_ws_send? Or, if so, why? (4) Is best practices, for curl_ws_send under a multl_handle, to be in a tight loop, (perhaps with a 1 ms delay(?)), around the curl_ws_send packet queuing [in case of CURLE_AGAIN]. (5) Or should the WebSocket pipe simply be a separate easy_handle by itself, outside of the multi_handle, and merely let the multi_handle take care of a pool of the sporadic REST requests (to the same Server domain)? Thanks very much for your kind answers. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
|
(6) In particular, if curl_ws_send under multi_handle returns, can you delete the message buffer (because it's been sent already), or do you have to wait until curl_multi_perform successfully sends it out the door (because it's still pending, and curl_ws_send doesn't make a copy)? Which one actually owns the char * buffer you pass to it? |
Beta Was this translation helpful? Give feedback.
-
|
In general, As for usage, Using |
Beta Was this translation helpful? Give feedback.
-
|
wss and ws is enabled by default these days, assuming that a TLS library is
also configured. You'll have to provide more details of the problems you're
seeing if you'd like help.
|
Beta Was this translation helpful? Give feedback.
In general,
curl_ws_send()can returnCURLE_AGAINon any call. If it does return OK and the amount returned insentis the amount written, the data in the buffer has either been transmitted or is queue in curl's internal send buffers. The application can then do with its buffer whatever it wants.As for usage,
curl_ws_send()was intended to be used more in a "standalone", single transfer application. Since curl 8.16.0, libcurl supports theCURLOPT_READFUNCTIONfor sending data on a websocket. I wrote a blog post about this.Using
CURLOPT_READFUNCTIONfor sending is the recommended way to use websocket in a multi handle. It should give a cleaner application code with no worries about EAGAI…