- From: Adam Bergkvist <adam.bergkvist@ericsson.com>
- Date: Thu, 6 Sep 2012 16:19:11 +0200
- To: Randell Jesup <randell-ietf@jesup.org>
- CC: "public-webrtc@w3.org >> \"public-webrtc@w3.org\"" <public-webrtc@w3.org>
Hi Thanks for putting together this summary. On 2012-08-31 23:05, Randell Jesup wrote: > So, on a totally different topic: > > We discussed the DataChannels API at the Stockholm Interim. I'd like to > move this part of the spec forward, as Mozilla has an implementation in > testing. > > The API, per the decisions at the Interim and mailing list is based > closely on the WebSockets interface. For example, you are supposed to > wait for onopen to fire before calling send(), at both ends. (The > low-level IETF protocol supports sending before onopen, but WebSockets > doesn't.) Currently I have no limit on send(DOMString); WebSockets > limits DOMStrings to 123 characters. > > I should note that the immediately-following IETF Interim appeared to > have the opposite conclusion on onopen and send(), and so the IETF > protocol design allows sending immediately, while the API I propose for > WebRTC DataChannels here does not. > > Supported channel types are reliable (and and out of order) channels, > unreliable and partly-reliable channels. (See the dictionary below.) > What role do partly-reliable channels have here? I don't see a natural way to expose such channels to JavaScript ATM since we put the transport properties on the channel and not on every package. > I'd *REALLY* like to move forward on resolving the open issues listed > below, as we're preparing to expose a preliminary DataChannels > implementation. Thanks. Sounds great! > > Open Issues: > ========== > > When can createDataChannel() be called? > ---------------------------------------------------------- > > Currently pc.createDataChannel() must be called after onconnected > fires. This was a point of discussion at the meeting and on the rtcweb > list, since DataChannels need some RTTs to establish; allowing the > application to pre-request data channels would allow them to be included > in the signaling (and thus save 1 RTT off the setup time). > What triggers the onconnected callback? > In order to allow pc.createDataChannel() to be called earlier the only > difference at the offerer's JS API level would be whether you can do: > > pc = new PeerConnection(...); > pc.addStream(...); > pc.createDataChannel("foo",{}); > pc.createOffer(...); > > etc. On the receive side, there's no way to reject a DataChannel (just > as there's no way to reject one before it's created after the > PeerConnection is connected). You can avoid setting onDataChannel or > respond to onDataChannel by closing it if you don't want it. The > receiver would be able to call pc.createDataChannel() before > createAnswer(). In all cases the channel isn't usable until onopen fires. > > > Do we need a DataConnection object? > ----------------------------------------------------- > > It was suggested that we have a DataConnection object, and hang > createDataChannel off of that. (see the thread "DataConnection objects" > from June.) Doing so would minorly reduce the number of methods on > PeerConnection (by moving onconnection/onclosedconnection/ondatachannel > to it, and maybe an attribute for initial number of streams). > > Pros: > * It gives you a clear way to easily drop all DataChannels. > * It gives you an easy point to query the association (mostly for > maxstreams I'd guess, perhaps for total bytes queued across all > DataChannels). > * A spec for a DataConnection object might be useful in some other > context in the future - but it always could be added later if needed. > (You could even indicate that PeerConnection implements DataConnection > if you wanted.) > * It does give you a clear way to say "Don't bother to open an > association" if you don't need one. > * You could add more DataConnections to a PeerConnections (but what does > that gain you?) > * Allows future extension to allow other protocols to be used over the > connection/association. > * Gives you something to hang an application identifier off of - but the > application can do that in other ways. > > Cons: > * More objects, more code required to set up a call with little benefit > to the current usecases. > * If you want to add a DataConnection later, it will require a renegotiation > * Answering requires a few extra steps to see if the offerer offered a > DataConnection. > > Overall, I'm very mildly in favor of adding the DataConnection object, > because it might be useful in some other contexts in the future. I do > think it complicates PeerConnection slightly, but only slightly (less > methods, but PeerConnection now needs to trigger renegotiation when > createDataConnection is called.) > I'm still a bit hesitant to insert another object. However, if we need the extra state machine (onconnection and onclosedconnection) I'm, on the other hand, a bit hesitant to just add that to PeerConnection as well (since it already exposes two types of states). > Label glare: > --------------- > A previous discussion ("Data API symmetry", in April/May) covered this. > This is the "what happens if both sides call createDataChannel("foo",{}) > at the same time" question. You can: > > 1) Create two channels labelled "foo". Each side would get an onopen to > their createDataChannel, and each would get an onDataChannel and onopen > for the one created by the other side. Handling the glare would be the > application's domain. > 2) Fail both (or find some agreed-on tiebreaker that lets you have one > fail and the other succeed). > 3) Create one channel labelled "foo", and each side would believe they > created it. Both would simply get "onopen", and it might even come > faster than normal. NOTE: if the two sides select different options for > the channel, then you still may need to return errors! (or create > channels with the same label) > > #3 is mildly appealing, until you think about how you handle errors with > disagreement on reliability. So I think I end up preferring #1. #3 > also implies you should have a unique label for each channel, to avoid > confusions with opening multiple channels with the same name at the same > time when the other side tries to as well. > Since we want to support the "create at A, dispatch at B"-method I agree to #1. #3 also comes with timing issues when channels can be created by both "label matching" and "create at A, dispatch at B"-methods. How long should you wait for a matching label before dispatching a channel on the B-side instead? > > Attributes: > ------------- > Is the single "reliable" attribute enough? Do we need to expose the > dict entries? Do we need a FindDataChannel(label) to get a reference to > an existing channel? > > (My opinion: Probably no to all of these, though I can see exposing the > dict entries.) > I think a reliable property is preferable since the developer doesn't have to derive what reliable is from a set of other properties. It shouldn't prevent us from exposing other properties (later) to tweak the transfer mode. > > This is the dictionary for RTCPeerConnection's createDataChannel() > method: (xpidl) > > /* If either maxRetransmitTime or maxRetransmitNum are set, it's > unreliable, else it's a reliable channel. If both are set it's an > error. outOfOrderAllowed can be used with any type of channel. The > equivalent of UDP is { outOfOrderAllowed: true, maxRetransmitNum: 0 }. > The TCP equivalent is {}. */ > > dictionary DataChannelInit { > boolean outOfOrderAllowed; > unsigned short maxRetransmitTime; // in ms > unsigned short maxRetransmitNum; > }; > > > And in PeerConnection: (xpidl) > > /* Data channel */ > nsIDOMDataChannel createDataChannel([optional] in ACString label, > /* DataChannelInit */ [optional] in jsval options); > attribute RTCPeerConnectionCallbackVoid onConnection; > attribute RTCPeerConnectionCallbackVoid onClosedConnection; > attribute RTCPeerConnectionCallback onDataChannel; This is an EventHandler (not a callback) with an associated DataChannelEvent in the current specification. onConnection and onClosedConnection should also be EventHandlers for consistency with the rest of the spec. /Adam > > This is the webidl for DataChannel I have currently (note: it might have > errors as we use xpidl internally, though we're switching to webidl). > > interface DataChannel : EventTarget { > [Infallible] > readonly attribute DOMString label; > > [Infallible] > readonly attribute boolean reliable; > > // ready state > const unsigned short CONNECTING = 0; > const unsigned short OPEN = 1; > const unsigned short CLOSING = 2; > const unsigned short CLOSED = 3; > > [Infallible] > readonly attribute unsigned short readyState; > > [Infallible] > readonly attribute unsigned long bufferedAmount; > > [TreatNonCallableAsNull, GetterInfallible] > attribute Function? onopen; > > [TreatNonCallableAsNull, GetterInfallible] > attribute Function? onerror; > > [TreatNonCallableAsNull, GetterInfallible] > attribute Function? onclose; > > [Infallible] > readonly attribute DOMString extensions; > > [Infallible] > readonly attribute DOMString protocol; > > void close(); > > // messaging > [TreatNonCallableAsNull, GetterInfallible] > attribute Function? onmessage; > > [GetterInfallible] > attribute DOMString binaryType; > > void send(DOMString data); > void send(Blob data); > void send(ArrayBuffer data); > }; > >
Received on Thursday, 6 September 2012 14:19:40 UTC