- From: Stefan Hakansson LK <stefan.lk.hakansson@ericsson.com>
- Date: Mon, 3 Sep 2012 15:27:24 +0200
- To: public-webrtc@w3.org
On 08/31/2012 11:05 PM, 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.)
>
> 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.
>
> 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).
I think this makes sense.
>
> 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(...);
or just (if you're only going to do data):
pc = new PeerConnection(...);
pc.createDataChannel("foo",{});
=== "negotiationneeded" fires ===
pc.createOffer(...);
I don't see a reason why you would need to create a PeerConnection, wait
for onopen, and then createDataChannel.
>
> 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 don't have a strong view.
>
>
> 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.
+1, I also think #1 makes most sense.
>
>
> 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?
To me, the single "reliable" attribute seems enough for a first version,
but if others want more it should be added (after all, a reason for
using a dictionary was to enable the addition of more things as we see
need).
>
> (My opinion: Probably no to all of these, though I can see exposing the
> dict entries.)
>
>
>
> 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 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 Monday, 3 September 2012 13:27:54 UTC