Yes, it would be nice to have just one callback for all WS modes (RAW, FRAME, 
MESSAGE) but using CURLOPT_WRITEFUNCTION callback for that purpose doesn't seem 
like an optimal solution to me because of the problems related to passing curl 
handle to it and making a function call to get WS context metadata.

All WS levels above RAW (frames, messages) require using WS context metadata 
for a WS data chunk to use it properly, and calling 
'curl_ws_metadata(curl_handle, ...)' in every CURLOPT_WRITEFUNCTION callback 
seems as a too high price.
No matter how fast is libcurl searching mechanism used to find WS "context 
data" by a curl handle, it can't compare to the instant time which a pointer to 
WS "context data" passed in the "write callback" provides.

And if we look at typical WS frameworks, they provide WS metadata as part of 
their WS events and callbacks.

I think if we separate CURLOPT_WRITEFUNCTION callback (Raw data) from 
CURLOPT_WS_WRITEFUNCTION callback (WS data) it will not really make things 
obscure, especially for folks familiar with WebSockets.
The CURLOPT_WRITEFUNCTION will carry the same meaning - opaque HTTP data and 
CURLOPT_WS_WRITEFUNCTION callback will carry WS payloads with WS metadata 
available (frame or message depending on the context).

And we can extend CURLOPT_WS_WRITEFUNCTION to an even more generic callback -  
"high_level_protocol_write_function " - a callback which can be used to pass 
high-level protocol data running on top of HTTP (or some other transport 
protocol).

This callback can have parameters:  protocol (WS in our case), data, size, 
protocol_context, userdata (maybe some more), and can be used as a general 
mechanism for protocols like WS.
With this approach, the CURLOPT_WRITEFUNCTION will be always kept as a callback 
for the "primary" transport protocol (like HTTP for WS) - and provide raw data 
carried over that protocol.

And I think that such separation between the low-level transport layer and 
high-level protocol layers is not difficult to understand and document, and it 
provides a quite flexible mechanism for implementing data callbacks for complex 
protocols with many options.

Thanks,
Dmitry Karpov


-----Original Message-----
From: Daniel Stenberg <dan...@haxx.se> 
Sent: Saturday, June 18, 2022 4:08 AM
To: Dmitry Karpov via curl-library <curl-library@lists.haxx.se>
Cc: Dmitry Karpov <dkar...@roku.com>
Subject: RE: About a websockets write callback

On Fri, 17 Jun 2022, Dmitry Karpov via curl-library wrote:

> 1. CURLOPT_WRITEFUNCTION callback - provides raw WS data after initial 
> WS negotiation over HTTP is done.

>       - This would allow to plugin easily existing custom WS implementations
>       that use their own frame parsing and message assembling.

Oh yes that's a neat idea! I like this.

> 2. WS_FRAME_WRITEFUNC callback - provides parsed WS frame information 
> - header and frame data.
>       - This would allow to provide custom WS extensions, like multiplexing 
> etc.

I think I prefer to re-use the same callback, in particular if you think of 
applications that would use a mix of websocket and other protocols to download 
data. But in the frame-parse mode there needs to be a way for the application 
to figure out the parsed details of the frame.

> 3. WS_MSG_WRITEFUNC callback - provides assembled WS message 
> information - message data and metadata.

I think I prefer to have an option for "ws mode" that would be RAW, FRAME or 
MESSAGE and have the same callback used for all of them. But the 'MESSAGE' 
mode might be something I save for a later PR once RAW and FRAME have landed 
work.

Having the same callback also removes the problems of having mulitple mutually 
exclusive options and protocol-specific behaviors for options == easier to 
document and for users to understand the data flow.

-- 

  / daniel.haxx.se
  | Commercial curl support up to 24x7 is available!
  | Private help, bug fixes, support, ports, new features
  | https://curl.se/support.html
-- 
Unsubscribe: https://lists.haxx.se/listinfo/curl-library
Etiquette:   https://curl.se/mail/etiquette.html

Reply via email to