Re: Improvements suggestion for DataChannels

Sorry for the delay, I have had some busy weeks on work and with the exams,
and also I wanted to test in profundity the usability of DataChannels as
how they are currently defined on the spec.

After doing that tests, I have learned several things:

* if you created some DataChannels on one side (and probably also if you
added some streams, too), only this side will have them since the
ondatachannel event is only dispatched after the PeerConnection objects
signalingState change to 'stable', allowing to use this trick to know what
endpoint initiated the connection (a feature that, by the way, would be
lost if a datachannel event were dispatched on the creator endpoint as I
proposed... so I've changed my mind on this point).

* when the ondatachannel event is dispatched, at least on Chrome v33 the
DataChannel readyState attribute was 'open' instead of 'connecting' as
according to the spec, and not only that, it was later dispatched the
DataChannel 'open' event. (This lead me a full day of debugging last
weekend...)

* due to the previous point, I think seriously that DataChannel (and by
extension, all WebRTC classes) should support promises to prevent this kind
of situations.

* as you predicted, since I was able to create a shim to add support for
PeerConnection.getDataChannels(), I have been able to do it at application
level and also in a more optimized way (just store the DataChannels I was
interested to, and just have a reference for them when the PeerConnection
got stable without needing it later), but the problem is about how to
easily identify what DataChannels are from what PeerConnection object, and
since I was not able to attach them using closures (I'm sharing a lot of
code between sender and receiving peers) the only solutions I found
feasable were to use a hash of arrays using as key an ID for each peer...
or just add the list of DataChannels to the PeerConnection instance, that
it's the easiest way but also the one that I was trying to evade.

So as conclussion, I have to admit that with the current specification it's
possible to achieve the same purposses that my propositions about a) an
indicator about who started the PeerConnection and the creation of the
DataChannel, and b) a way to get the list of DataChannels of a
PeerConnection instance and they are just simple syntactic sugar, but the
fact is that the current spec API doesn't allow an easy nor elegant way to
get that info, so I still believe that this functionality should be added,
in the worst case to be more homogeneous with the PeerConnection streams
related methods counterpart.


El 14/01/2014 08:29, "Adam Bergkvist" <adam.bergkvist@ericsson.com>
escribió:

On 2014-01-13 22:28, piranna@gmail.com wrote:

>  (third bullet) I would suggest using the open event on the creating side
>>> for
>>> this. You get the channel from the target property of the event, and the
>>> channel is in the open state; same state as in the "datachannel" event
>>> handler on the receiving side.
>>>
>>>  I've re-read about this point on the latest specification (10
> September 2013) and if I understood it correctly, it's not defined to
> work as you said:
>
> "
> A RTCDataChannel, created with createDataChannel() or dispatched via a
> RTCDataChannelEvent, MUST initially be in the connecting state. When
> the RTCDataChannel object's underlying data transport is ready, the
> user agent MUST announce the RTCDataChannel as open.
>
> When the user agent is to announce a RTCDataChannel as open, the user
> agent MUST queue a task to run the following steps:
>
> If the associated RTCPeerConnection object's RTCPeerConnection
> signalingState is closed, abort these steps.
>
> Let channel be the RTCDataChannel object to be announced.
>
> Set channel's readyState attribute to open.
>
> Fire a simple event named open at channel.
>
> When an underlying data transport is to be announced (the other peer
> created a channel with negotiated unset or set to false), the user
> agent of the peer that did not initiate the creation process MUST
> queue a task to run the following steps:
>
> If the associated RTCPeerConnection object's RTCPeerConnection
> signalingState is closed, abort these steps.
>
> Let channel be a newly created RTCDataChannel object.
>
> Let configuration be an information bundle received from the other
> peer as a part of the process to establish the underlying data channel
> described by the WebRTC DataChannel Protocol specification.
>
> Initialize channel's label, ordered, maxRetransmitTime,
> maxRetransmits, protocol, negotiated and id attributes to their
> corresponding values in configuration.
>
> Set channel's readyState attribute to connecting.
>
> Fire a datachannel event named datachannel with channel at the
> RTCPeerConnection object.
> "
>
> If I understood it correctly, 'datachannel' event is dispatched on the
> receiver endpoint to notify that a new DataChannel has been created,
> but it's on the 'connecting' state, not the 'open' one, and that the
> 'open' event should be dispatched on both endpoints (starter and
> receiver) when the connection is ready and not only on the starter
> one. Is it correct? If so, I don't see any problem to also dispatch
> the PeerConnection 'datachannel' event on the starter endpoint, since
> definitely it's not doing the same task that the DataChannel 'open'
> one...
>

Your interpretation is correct. We switched to the "open on both sides"
approach a while ago.

But then there you have your symmetric event; if you need to do similar
work on both sides as the result of a event, can't you use the open event?
Generally it's much more convenient to work with synchronous APIs than with
events and callbacks. Since createDataChannel() is a factory method that
can be synchronous, I think it's more intuitive to keep it like that.

/Adam

Received on Friday, 7 February 2014 22:48:00 UTC