A proposal for a solution to "parallel forking" #29

aboba opened this Issue Feb 1, 2014 · 1 comment


None yet

1 participant

aboba commented Feb 1, 2014

From: Peter Thatcher pthatcher@google.com
To: public-orca@w3.org
Date: Fri, 31 Jan 2014 16:10:59 -0800
Subject: A proposal for a solution to "parallel forking"
URL: http://lists.w3.org/Archives/Public/public-orca/2014Feb/0000.html

A use case that isn't (well?) supported by the WebRTC 1.0 spec is what
we sometimes call "parallel forking", which basically means that a
local endpoint sends signalling information to many remote endpoints
and then can receive back signalling and then send and receive media
to/from more than one endpoint. A solution was previously
discussed in the WebRTC WG as "cloning", but seemed too complicated
for the 1.0 API to be practical.

An example of how this would be useful is setting up data channels
with multiple peers without having to allocate separate ICE parameters
and candidates for each peer. You could, with parallel forking, send
up one set of local ICE parameters to a server which could be used by
all remote peers to connect to the local peer.

The good news is that the ORTC components we already have
(IceTransport, DtlsTransport, RtpSender, RtpReceiver, SctpTransport)
give a JS app just about everything it needs for this use case. A JS
app can create multiples of DtlsTransport, RtpSender, RtpReceiver, and
SctpTransport for each endpoint it wants to talk to.

The bad news is that we're missing one piece: the ability to have
several IceTransports that share the same ICE local parameters and
local candidates. If we could just do that, then we would have
everything we need to support parallel forking. I think there are
basically two ways we could allow for this in the ORTC API:

  1. Add some kind of IceTransport.fork() method which gives you a copy
    of the IceTransport object which can then have different remote
    parameters and remote candidates, but the same local parameters and
    local candidates. Something like this:

var iceOptions = ...;
var iceParent = new RTCIceTransport(RTCIceRole.controlling, iceOptions);
sendInitiate(iceParent.getLocalParameters(), function(response) {
// We may get N responses
var ice = iceParent.fork();
var ice.setRemoteParameters(repsonse.iceParameters);
// ... setup DTLS, RTP, SCTP, etc.
iceParent.onlocalcandidate = sendLocalCandidate;

While I like the apparent simplicity of this approach, it does run
into a lot of weird questions, like: what if I change something on the
parent; does that effect the children? Is it best to keep a parent
laying around that's only used for forking? What if I need to change
the ICE role? Questions like that would probably plague us for a long

  1. Add a new object which is explicitly shared between different
    IceTransports. It acts as the "ice parent" in the previous example,
    and if you want more than one IceTransport with the same local
    parameters and candidates, you make one of these new parent objects
    and then explicitly share it between IceTransports. Something like

var iceOptions = ...;
var iceListener = new RTCIceListener(iceOptions);
sendInitiate(iceListener.getLocalParameters(), function(response) {
// We may get N responses
var ice = new RTCIceTransport(RTCIceRole.controlling, iceListener);
var ice.setRemoteParameters(repsonse.iceParameters);
// ... setup DTLS, RTP, SCTP, etc.

iceListener.oncandidate = sendLocalCandidate;

This has the advantage that it's much more clear and explicit is going
on and there aren't all those tricky edge cases about a parent/child
relationship between IceTransports. I think we'll be happier
long-term with something like this. This is just like the purpose and
design of the RTCSocket object that was in ORTC previously, but fits
in with our new IceTransport model.

So, I propose we add something like the following object, which will
give us the last remaining piece to support parallel forking:

[Constructor(optional RTCIceListenerOptions options)]
interface RTCIceListener {
readonly attribute RTCIceListenerOptions options;

RTCIceParameters getLocalParameters();
readonly attribute sequence localCandidates;

void start();
void stop();

attribute EventHandler? onlocalcandidate;
attribute EventHandler? ongatherfailure;

I much the prefer the second solution, and I think it would be a great
way to support parallel forking and is an example of something that
the ORTC model can easily support that was too complex to be practical
in the 1.0 API.

aboba commented Feb 15, 2014

Please review the fixes relating to this issue in the latest ORTC Editor's draft:

If there are any remaining concerns, please post these to the public-orca@w3.org mailing list.

@aboba aboba closed this Feb 15, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment