> could libcurl wait for all the fragmented messages to arrive, then concat > them and serve the completed message to the calling application?
I don't think it is possible in all the cases. WebSocket text/data messages can have 64-bit length, so it is just not possible to assemble large messages. I implemented WebSocket protocol in some C++ curl-based client and I used the following approach: 1. Notify client that some WS not control message (i.e. text/data) has arrived. 2. In the notification callback, Client either provides a buffer to store the message (can be useful for short messages) or data writing callback to store large messages (where data concatenation is not feasible). - If provided buffer is too small to hold the message, then we need to handle it as WebSocket protocol prescribes - close WS connection with 1009 'Buffer too small' error code. 3. I also provided a special callback for incoming control messages (i.e. Ping) while large data messages are being received, so client can handle multiple messages (one large data and multiple control messages at the same time) at the same time. > Alternatively, a curl_ws_send_ping and curl_ws_send_pong would be useful. > Also, considering sending a pong response when a ping request is sent > automatically, unless it's specified by the calling program somehow. Yes, I agree that automatic reply on Ping is part of a good WS client. > Using a callback function may be a solution, when a message is received, > libcurl calls a function specified by the application, something like > cur_ws_on_message_received() I used two callbacks in my WS client implementation: - onMessageArrived() (indicating arrival of the first frame of the message and asking client code to specify a way where/how to write the incoming message data) - onMessageReceived() (indicating that the message was successfully received). To simplify client's life, I allowed to specify the WS receive buffer as WebSocket option, so in most of the use cases, my client code used just onMessageReceived(). Talking about some WS implementation difficulties, I would say that message multiplexing (sending/receiving large data/text message intermixed with control messages - control messages should be sent/received as high-priority interrupts for data messages), proper protocol error handling and protocol extensions (like compressing) gave me some headaches. WebSocket protocol is very specific about how and when WS connection should handle certain errors, and which status codes should be used in different connection closure cases, so sometimes some specific transport errors (like Tls handshake errors) should be explicitly handled and reported as WS connection closures with specific status codes (i.e. 1015 'TLS handshake failure'). Thanks, Dmitry Karpov -----Original Message----- From: curl-library <curl-library-boun...@cool.haxx.se> On Behalf Of Nicolas Mora via curl-library Sent: Friday, July 2, 2021 4:48 PM To: libcurl development <curl-library@cool.haxx.se> Cc: Nicolas Mora <nico...@babelouest.org>; Daniel Stenberg <dan...@haxx.se> Subject: Re: curl websockets Le 2021-07-02 à 17 h 53, Daniel Stenberg via curl-library a écrit : >> >> This will make it impossible to specify a continuation frame rather >> than a data frame. (Context: when a message is fragmented, the >> message’s first frame is text/binary, and the latter ones are >> continuation.) > > "CURL_WS_MORE" is my currently suggested flag to say to libcurl that > there's more data coming that belongs to the same data packet. Doesn't > that work? > could libcurl wait for all the fragmented messages to arrive, then concat them and serve the completed message to the calling application? >> Alternatively, have separate curl_ws_send_text and >> curl_ws_send_binary functions? > > That could certainly work and would save users sending text from > having to set a "this is text" bit. My personal preference is to > rather keep it to one function with the bits for type, but I'm here to > listen in what peeps want and I will not push my own preferences if I'm in a > minority. > Alternatively, a curl_ws_send_ping and curl_ws_send_pong would be useful. Also, considering sending a pong response when a ping request is sent automatically, unless it's specified by the calling program somehow. > > Yes, sorry I didn't even think about that. I'm positive users will > immediately come up with use cases where they want 22 parallel > websocket connections going on so they cannot block. Or perhaps we can > offer some kind of blocking abilitites, but non-blocking is a must-support > feature. > > Another thing that struck me is that we probably want to offer a > decent way to do non-blocking ws-connects as well for the > 22-connections user who won't accept that the application will block once for > each setup... > Couldn't libcurl have both? a blocking and a non-blocking curl_ws_recv() function? >> Having the caller call curl_ws_recv() directly would mean that that >> same caller would need to know when the socket has data to read. I >> don’t know if that’s always a safe assumption. > > Yeah, that's one of my outstanding questions. How do we do that? > Using a callback function may be a solution, when a message is received, libcurl calls a function specified by the application, something like cur_ws_on_message_received() /Nicolas ------------------------------------------------------------------- Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html ------------------------------------------------------------------- Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html