原作者:Philipp Hancke(原文链接)
翻译:刘通
我之前写过一篇关于ICE失败的文章。那时候我只是分析了初始化时候的失败,并没有讨论通话建立成功之后发生的ICE失败。现在我们来探讨一下ICE重启的问题。
当WebRTC连接失败的时候,我们可以看到ICE连接状态也发生了改变。你可以加入一个事件监控:
对于我们来说,iceConnectionState的值中我们所感兴趣的是disconnected和failed。简单的来说,disconnected是指连接被中断,但是还有可能不做任何工作就又可以重新连接。Failed状态更像是一个持续的错误状态,你需要将ICE重启才能解决这个问题。通常,当连接中断的时候,ICE连接状态先是变成disconnected,过一段时间状态会变为failed。
当ICE连接状态变成failed之后你就可以进行ICE重启了。这意味着你需要收集新的候选项,将他们送至对等端然后从对等端继续收集新的候选项。希望这样就可以把连接重新建立起来,如下面代码所示(点击查看完整示例):
你会注意到SDP中的ice-ufrag和ice-pwd属性发生了改变。将其发送给对等端,之后对等端将会用这些变了的参数产生新的应答。
我的同事Dag-Inge今年三月进行了了ICE重启测试,只要一开始ICE重启Firefox浏览器就是闪退。
但是我们从未对ICE重启工作以及产生的冲击进行过任何评测。首先,让我们设定一个常见的100k的数据集。
然后,我们需要看ICE是否进行了重启。可以通过观察iceRestart的createOffer通话来实现。
从上图我们可以看出大约8.7%的连接进行了ICE重启的尝试。通过几个月的观察,我们发现这个比例大约维持在7.5%。
这些数据说明了没有ICE重启功能就提供WebRTC服务不是一个好主意,即使是这样用户也可能只是选择刷新整个网页来起到重启ICE的作用。不幸的是,现在网上没有多少写ICE重启的文章,希望本文章能够对你们起到一点作用。
所以我们有8.7%的通话进行了ICE重启。现在我们需要查看一下他们是否进行了任何修改。我们通过观察oniceconnectionstatechange的值是connected还是completed来决定ice重启是否成功:
上图表示大约有三分之二的ICE重启重新建立了连接,意味着更高的通话成功率和更好的用户体验!
但是仍有30%的失败率让人很担忧,我们能解释其产生的原因吗?大多数情况造成这些连接失败的原因是远端用户离开了。我们可以通过检查在createOffer之后是否产生了一个相应的setRemoteDescription调用来监测是否发生了上种情况。如果没有出现调用,说明远端用户已经失去了信令连接(可能他们已经把页面关闭了),或者没有运行ICE重启:
所以在不成功的ICE重启之中有85%的情况我们无法从对等端哪里获得新的应答。可能意味着他们已经不再与信令服务器有任何连接了。他们可能已经关掉了网页,或者(几率没有前者大)意味着他们的浏览器版本不能够实施ICE重启;Firefox最近才能在47版本中进行这项工作。这种情况除了给用户弹出提示框说明连接失败以外没有什么更好的办法了。
剩下的400个实例需要进行更深入详细的调查,在其中肯定是存在一些bug的。当然如果对更大量的信令失败进行统计的话,发现bug的几率会增加,但是工作的优先级可能不允许你这么干。。。
既然我们把ICE重启视为改善WebRTC服务质量的一个重要因素。ICE重启也是当用户的网络连接情况从WiFi切换到移动流量而产生的问题的解决方案。最近我们也发现Google的Duo可能不会用ICE重启,而会选择持续指派的方法来解决连接失败的问题。