Re: WebRTC and backpressure (how to stop reading?)

On 25 Mar 2014, at 19:16, Nicholas Wilson <nicholas@nicholaswilson.me.uk> wrote:

> Dear all,
> 
> I've started writing a C++ application that uses WebRTC data channels,
> but I'm running into a problem straight away:
> 
> How can I stop reading from the channel?
> 
> The JavaScript data channel API seems to have the same problem that
> the JavaScript WebSocket API had, namely that it's not easy/possible
> to stop reading and apply backpressure to the channel. For the
> WebSocket spec, I made a request about this on the WHATWG list a
> couple of years ago, but it was already too late for the spec to be
> changed. Would it be possible to make sure that this key use-case is
> supported for WebRTC?
> 
> WebRTC is meant to make things easy for developers of webapps: forcing
> them to implement application-level flowcontrol on top of a perfectly
> good flow-controlled channel seems harmful, and will result in lower
> throughput performance than using the native SCTP buffering. We want
> our RTCDataChannel-based apps to be as fast as possible!
> 
> The underlying SCTP channel fully supports applying backpressure, it's
> only the webrtc::DataChannelInterface API which doesn't support it.
Could you explain how you can the underlying SCTP channel supports
backpressure per stream? SCTP supports a flow control which affects
all streams, but not a flowcontrol per stream.
> Similarly the WebRTC JavaScript API uses the same onmessage-style
> handling of incoming data, making it impossible to punt the data to a
> worker thread without risking overwhelming it.
> 
> The use-case is simple and clear: If I want to implement file transfer
> to a WebRTC client (say), it's not possible for the browser to fully
> buffer the data (it might be a 30GB disk image I'm sending, more than
> my RAM). The WebRTC read end needs to have a way to stop reading (if
> it plans to do any processing on the data). This would let the SCTP
> recv buff fill up, so the window would shrink, and the send end would
> start backing up data. The sending end in turn ideally needs to have
> an onwrite callback, so that if the application sees the
> bufferedAmount increasing, it can implement blocking semantics, and
> resume sending when the bufferedAmount drops. Without an onwrite
> callback, the application has to poll until the bufferedAmount goes
> down; this stinks a bit but is just about acceptable.
> 
> I have the time to add the relevant code to the C++ WebRTC.org library
> -- but is there interest? We need the JavaScript spec to be tweaked,
> and changes to the glue in both Firefox and Chrome, for it to be
> worthwhile. I really hope it's possible to get this change pushed
> forward, or we'll be left in the same bad situation as for WebSockets,
> where it's now too late to fix the problem!
> 
> The WHATWG streams interface is a clear example of a useful JavaScript
> interface that simply can't be implemented on top of the current
> WebRTC or WebSocket APIs (https://github.com/whatwg/streams). Please
> correct me though if I'm wrong!
> 
> The required changes for the JavaScript spec would be the addition of
> a single `setReadEnabled(bool)` method or a settable attribute on
> RTCDataChannel. Polling makes programmers sad :(, so it would be
> highly desirable also to add an onwrite attribute of type
> EventHandler, for a callback when the write buffer clears.
> Corresponding methods would need to be added to
> webrtc::DataChannelObserver. The plumbing is essentially
> straightforward, except for some threading shenanigans in libusrsctp
> which doesn't exactly have an ideal external interface.
It does not only have an ideal external interface, SCTP doesn't
provide a flowcontrol per stream. Not ready data on one stream
would affect the other streams...

Best regards
Michael
> 
> Thanks for any comments,
> Nicholas
> 
> -----
> Nicholas Wilson: nicholas@nicholaswilson.me.uk
> Site and blog: www.nicholaswilson.me.uk
> 
> 
> 

Received on Wednesday, 26 March 2014 09:17:31 UTC