- From: Adam Bergkvist <adam.bergkvist@ericsson.com>
- Date: Wed, 25 Apr 2012 16:04:25 +0200
- To: "public-webrtc@w3.org" <public-webrtc@w3.org>
Hi In a previous mail conversation we discussed the data channel setup process; as a starting point we had the createDataChannel()@A -> "datachannel event"@B. The question was if we also should support the automatic label matching approach where each peer could call createDataChannel("label") and if the labels were the same, the data channels would be connected and the "open" event would trigger on each side. The result of the discussion was that the two approaches were tricky to combine since it wasn't straightforward to determine if a "datachannel" event should be triggered at the other peer or if the other peer may call createDataChannel() with a matching label in the near future. In the recent discussions about the "open" event we have talked about symmetry and our current API is a bit asymmetric in some sense. Therefore I've done some coding where the current approach with a createDataChannel() call and a "datachannel" event is compared to the matching label approach, not combined with the first approach as in the previous discussion, but on its own. This means that in the matching label approach, a channel is not usable until a matching channel has been created on the other side. I've come up with two cases (A and B described below) and approaches #1 ("datachannel" event) and #2 (label matching) are applied to both. Case A demonstrates the two approaches when two data channels ("chat" and "extra") are set up as soon as the PeerConnection reaches the ACTIVE state ("open" event is triggered). I think this is a common use case when an application wants a set of data channels from the start. The symmetry of #2 is really advantageous in this case - the channels can simply be created and assigned to their corresponding variables. Both sides waits for the "open" event to get started. Approach #1 needs to decide who will create the channels and the receiving side needs to determine which dispatched channel that should go into which local variable. // Case A - #1 peerConn.onopen = function () { if (caller) { chatDataChan = peerConn.createDataChannel("chat", chatSettings); chatDataChan.onopen = startChat; chatDataChan.onmessage = showChatMessage; extraDataChan = peerConn.createDataChannel("extra", extraSettings); extraDataChan.onopen = startExtra; extraDataChan.onmessage = onExtraMessage; } peerConn.ondatachannel = function (evt) { var chan = evt.channel; if (chan.label == "chat") { chatDataChan = chan; startChat(); chatDataChan.onmessage = showChatMessage; } else { extraDataChan = chan; startExtra(); extraDataChan.onmessage = onExtraMessage; } }; }; //------------------------------------------------------------------------------ // Case A - #2 peerConn.onopen = function () { chatDataChan = peerConn.createDataChannel("chat", chatSettings); chatDataChan.onopen = startChat; chatDataChan.onmessage = showChatMessage; extraDataChan = peerConn.createDataChannel("extra", extraSettings); extraDataChan.onopen = startExtra; extraDataChan.onmessage = onExtraMessage; }; //============================================================================== In case B, one data channel is set up as the PeerConnection object reaches the ACTIVE state (as in case A), and an "extra" channel is set up as a response to a user action (button click in this case). Approach #1 has an advantage in case B since the API is based around one side initializing the data channel creation process. In approach #2, the JavaScript needs to signal that the other side should create a data channel with a specific label. However, in #1 there's a risk that two parallel data channels with the same label are created if both users clicks the add button simultaneously. In #2, the simultaneous clicks would actually set up the channel and the manual creation signaling from the other side can be discarded by both sides. // Case B - #1 peerConn.onopen = function () { if (caller) { chatDataChan = peerConn.createDataChannel("chat", chatSettings); chatDataChan.onopen = startChat; chatDataChan.onmessage = showChatMessage; } peerConn.ondatachannel = function (evt) { var chan = evt.channel; if (chan.label == "chat") { chatDataChan = chan; startChat(); chatDataChan.onmessage = showChatMessage; } else { extraDataChan = chan; startExtra(); extraDataChan.onmessage = onExtraMessage; } }; }; addButton.onclick = function () { if (extraDataChan) return; extraDataChan = peerConn.createDataChannel("extra", extraSettings); extraDataChan.onopen = startExtra; extraDataChan.onmessage = onExtraMessage; }; //------------------------------------------------------------------------------ // Case B - #2 peerConn.onopen = function () { chatDataChan = peerConn.createDataChannel("chat", chatSettings); chatDataChan.onopen = startChat; chatDataChan.onmessage = showChatMessage; }; addButton.onclick = function () { if (extraDataChan) return; viaWebServer.send("setup extra channel"); setupExtraChannel(); }; function setupExtraChanel() { extraDataChan = peerConn.createDataChannel("extra", extraSettings); extraDataChan.onopen = startExtra; extraDataChan.onmessage = onExtraMessage; } viaWebServer.onmessage = function (evt) { if (evt.data == "setup extra chanel" && !extraDataChannel) setupExtraChannel(); }; //============================================================================== Regarding the settings used when creating a new data channel, #2 does introduce an extra risk of failure if the settings mismatches (not possible in #1), but it's a programming error that will throw an exception. In the example "Case B - #2" above, the settings for the "extra" data channel is known to both sides since it's a symmetric application, but in the case where the initiating side has modified or created a new settings object, the settings needs to be transferred along with the request to tell the other side to create a data channel with a matching label. Thanks for reading all the way here. BR Adam
Received on Wednesday, 25 April 2012 14:04:58 UTC