Trickle/PreGathering interaction

The current specification contains two features that seem to interact in an
unclear
way:

- Pregathering (See S 4.3.1)
- Trickle ICE (i.e., the onicecandidate event)

The current text requires that the browser start gathering as soon as
the RTCPeerConnection is created and IceTransports is not "none":

    Create an ICE Agent as defined in [ICE] and let connection's
    RTCPeerConnection ICE Agent be that ICE Agent and provide it the
    STUN and TURN servers from the configuration array. The ICE Agent
    will proceed with gathering as soon as the IceTransports
    constraint is not set to "none". At this point the ICE Agent does
    not know how many ICE components it needs (and hence the number of
    candidates to gather), but it can make a reasonable assumption
    such as 2. As the RTCPeerConnection object gets more information,
    the ICE Agent can adjust the number of components.

Because the default value of IceTransports is set to a nonmandatory
"all", so this implies that implementations should start gathering
immediately on PC creation with the default constraints.


This raises the question of when we should be calling onicecandidate.
The spec implies that this should happen whenever we find out about
a new candidate:

    When the ICE Agent needs to notify the script about the candidate
    gathering progress, the user agent must queue a task to run the
    following steps:

    1. Let connection be the RTCPeerConnection object associated with this
ICE Agent.

    2. If connection's RTCPeerConnection signalingState is closed, abort
these steps.

    3. If the intent of the ICE Agent is to notify the script that:

    * A new candidate is available.

      Add the candidate to connection's localDescription and create a
      RTCIceCandidate object to represent the candidate. Let
      newCandidate be that object.

    * The gathering process is done.

      Set connection's ice gathering state to completed and let
      newCandidate be null.

    4. Fire a icecandidate event named icecandidate with newCandidate at
connection.

Note that this doesn't say anything about the current signalingState being
"stable" versus "have-local-offer", etc.

All of this implies that if you do:

   pc = new RTCPeerConnection();
   pc.onicecandidate = function(x) {
       ...
   }

And then nothing else, the onicecandidate function would get called some
nonzero number of times, depending on what the PC is using as its defaults
for the number of ICE components to gather [0]. This doesn't really
make sense (it isn't consistent with a simple JS implementation) and
IIRC isn't what we agreed.


I believe what we agreed is something like:

1. On PC instantiation, the browser starts gathering candidates based
   on the expected number of components.
2. Prior to createOffer/createAnswer, the candidates are stored but
   onicecandidate is not called.
3. When CreateOffer/CreateAnswer is called, any known candidates are
   returned with it.
4. Subsequent to this, onicecandidate is called.


Does this sound like what we agreed? Does it sound approximately
right? If not, you can stop reading and object not.

Assuming you think it's approximately right, there are some nitpicky
problems: do we start calling onicecandidate after CreateOffer() or
after SetLocal()? Neither of them seems ideal: in the first case, we
have to deal with the fact that there's no state associated with
having called CreateOffer() but not SetLocal().  In the second case,
what happens to candidates that are gathered after CreateOffer() but
before SetLocal()? Are they buffered and then emitted after
SetLocal()? In either case, what about multiple calls to CreateOffer()?

Do others have clear thoughts about this?

-Ekr


[0] I believe we agreed that there should be some fxn to indicate the
size of the pool to pre-gather, but I don't see that in the current
spec. Maybe I missed it. Regardless, as soon as we have pre-gathering,
this problem exists.

Received on Sunday, 18 August 2013 02:52:37 UTC