Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeout trigger _iceComplete if candidates seen. #353

Merged
merged 1 commit into from
Oct 24, 2018

Conversation

chr15m
Copy link
Contributor

@chr15m chr15m commented Sep 2, 2018

On some networks the iceStateChange=complete event will not fire until the browser times out, even though all valid and useful offer/answer candidates have already been gathered in the first milliseconds.

Examples of this occurring:

According to a Chromium developer here:

It's almost surely due to an interface that has an IP but no connectivity to the internet. We fail to get any response to our attempts to contact the STUN server, so we just time out.

In other words, on these networks there are valid routes to the internet but also invalid routes. Those invalid routes are confusing the offer gathering process into thinking it must keep trying.

This means that people on such networks can have 10s of seconds of delay in WebRTC offer creation time (consistently ~40s on my own network which experiences this issue) even though all valid candidates they are going to receive have been received in the first milliseconds of the offer process. The log in the bittorrent-tracker issue has a detailed example of this happening.

In the thread above Chromium developers suggest a JS time-out:

Seems like an application-specific decision.
...
Which is basically "use a timeout in JS", which is what I suggested

Similar patches have been suggested and implemented in other WebRTC projects:

This patch follows the same pattern and makes _iceComplete fire early and return the valid offers that have been gathered after some timeout. This only happens once the first valid candidate has been received. The timeout defaults to 5 seconds and can be modified by the user using opts.iceCompleteTimeout.

Let me know if you need any further information or if there are any changes required to this patch. Thanks for your consideration!

Side note which may be of interest. On the network where I see the 45s delay the following simple-peer tests also fail:

# ensure remote address and port are available right after connection
ok 24 peers connected
ok 25 peer1 remote address is present
not ok 26 peer1 remote port is present
  ---
    operator: ok
    expected: true
    actual:   0
    at: Peer.<anonymous> (/home/chrism/dev/simple-peer/test/basic.js:213:7)
    stack: |-
      Error: peer1 remote port is present
          at Test.assert [as _assert] (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:224:54)
          at Test.bound [as _assert] (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:76:32)
          at Test.assert (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:342:10)
          at Test.bound [as ok] (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:76:32)
          at Peer.<anonymous> (/home/chrism/dev/simple-peer/test/basic.js:213:7)
          at emitNone (events.js:106:13)
          at Peer.emit (events.js:208:7)
          at /home/chrism/dev/simple-peer/index.js:772:12
          at /home/chrism/dev/simple-peer/index.js:635:7
          at <anonymous>
  ...
ok 27 peer2 remote address is present
not ok 28 peer2 remote port is present
  ---
    operator: ok
    expected: true
    actual:   0
    at: Peer.<anonymous> (/home/chrism/dev/simple-peer/test/basic.js:217:9)
    stack: |-
      Error: peer2 remote port is present
          at Test.assert [as _assert] (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:224:54)
          at Test.bound [as _assert] (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:76:32)
          at Test.assert (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:342:10)
          at Test.bound [as ok] (/home/chrism/dev/simple-peer/node_modules/tape/lib/test.js:76:32)
          at Peer.<anonymous> (/home/chrism/dev/simple-peer/test/basic.js:217:9)
          at emitNone (events.js:106:13)
          at Peer.emit (events.js:208:7)
          at /home/chrism/dev/simple-peer/index.js:772:12
          at /home/chrism/dev/simple-peer/index.js:635:7
          at <anonymous>
  ...
ok 29 peer1 destroyed
ok 30 peer2 destroyed

chr15m added a commit to chr15m/bugout that referenced this pull request Sep 4, 2018
@t-mullen
Copy link
Collaborator

t-mullen commented Sep 11, 2018

So basically a timeout on ice gathering when trickle:false? Makes sense, I've noticed gathering some candidates can take a really long time, especially when using unresponsive STUN servers alongside active ones.

My only issue would be that ice candidates coming in after the timeout won't be exchanged with the remote peer. But I guess if you want to exchange candidates after an offer, you should use trickle.

LGTM. Great analysis too.

Copy link
Collaborator

@t-mullen t-mullen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't usually commit the build until a release.

On some networks the iceStateChange=complete will not fire until the
browser times out adding tens of seconds of latency even though all
valid candidates have been recieved. This patch makes _iceComplete fire
early and current offer return after some timeout if we've received
valid candidates.

See webtorrent/bittorrent-tracker#199 for further discussion.
@chr15m
Copy link
Contributor Author

chr15m commented Sep 11, 2018

@t-mullen thanks for your review! I've update the PR to remove the build artifact.

@DiegoRBaquero
Copy link
Collaborator

@feross needed.

@t-mullen t-mullen merged commit 4cf8516 into feross:master Oct 24, 2018
FredZeng pushed a commit to FredZeng/simple-peer that referenced this pull request Oct 14, 2023
Timeout trigger _iceComplete if candidates seen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants