我将Twilio Network Traversal Service用作本机应用程序的一部分working on来执行对等远程桌面连接。我们实现了相当于WebRTC数据通道(而不是WebRTC视频和音频协议)的WebRTC协议栈的子集。使用TURN中继时,TURN分配似乎在从会话开始开始的几分钟到最多12分钟之间的某个时间随机失效。这个问题看起来与此one非常相似,但是由于我未实现WebRTC音频/视频协议,因此在我看来,建议的解决方法(发送无声音频)是不可接受的。
在过去的两个星期中,我一直在努力解决这个问题,并将问题归结为Twilio服务本身。为了进行比较,我使用了一个基于网络的WebRTC数据通道演示,该示例使用了firefox和Xirsys TURN server cloud。我的wireshark捕获显示了Firefox与Twilio断开连接的过程,就像我的本机应用程序一样,而使用Xirsys服务器时,相同的Firefox演示并没有断开连接。
我最初使用的是Xirsys,但是由于他们的服务不稳定,因此我改用了Twilio,这就是为什么我宁愿让Twilio修复此问题,而不是回到Xirsys。至少,我希望有两个WebRTC托管服务提供商,我可以选择它们,我知道它们可以正常运行。这就是为什么我花时间详细解释该问题,以便得以解决。
以下是两个Wireshark捕获(过滤出了对等数据消息),它们显示了使用WebRTC数据通道和Twilio TURN中继服务器的Firefox:
第一次捕获4分钟后,第二次捕获约11分钟后,流量停止中继。在这两个捕获中,firefox检测到流量停止中继(在数据通道级别),并通过发送有效期为零的刷新请求数据包尝试正常断开连接。两次正常断开都会导致437分配不匹配错误,表明服务器甚至都不知道firefox试图正常关闭的分配。
在我的本机应用程序中,这通常采用CreatePermission Request消息的形式,该消息失败并显示438“错误的随机数”错误,这基本上是如果客户端尝试更新不再分配的权限时应该发生的情况存在。错误代码438通常表示“陈旧的随机数”,这并不是真正的错误,而是表示随机数已过期,客户端应使用“错误”消息中包含的新随机数再次尝试。我花了一些时间才弄清楚,但是即使错误代码为438,错误字符串也不相同。我已经观察到Xirsys出现了一个真正的过时的随机数错误,并成功地从错误响应中使用新的随机数更新了我的权限,因此我知道我可以在实现中正确处理这种情况。
这是我使用的WebRTC数据通道演示的源代码: https://github.com/devolutions/webrtc-demo
为了进行比较,这是使用Xirsys TURN服务器云的相同的firefox数据通道演示:
在此捕获中,我让演示运行了大约16分钟(它的工作时间更长,我尝试的最长时间是两个小时)。我们可以看到,在整个会话期间,流量一直在中继,并且FireFox成功发送CreatePermission请求。最后,通过断开WebRTC数据通道的firefox触发正常断开连接(而不是由于不再中继流量而被关闭)。与Twilio捕获相反,生存期为零的Refresh请求是成功的:Xirsys TURN服务器仍然知道分配情况,并按预期方式发送回成功响应。
应该注意,ICMP无法到达的错误是正常的,因为我认为在这种情况下,当响应返回时,firefox不再侦听给定的端口。换句话说,它发送的Refresh请求的生存期为零,并且不等待答案返回。
目前,我别无选择,只能返回Xirsys,但是我真的很想Twilio网络遍历服务是否可以修复。如果您还有其他疑问,请告诉我。
我已经上传了Wireshk捕获here供参考。
编辑:我已经修改了webrtc演示页面,使得当ice连接状态设置为“ disconnected”时,它不会关闭连接。现在,当冰连接状态变为“失败”时,我得到了真正的断开连接。但是,它实际上没有任何改变,因为在这种情况下,状态从“断开连接”变为“失败”仅需要几秒钟的时间。
由于我拥有新的相关屏幕截图和截图,因此我正在更新原始问题,以澄清Philipp Hancke指出的某些问题:
首先,这是修复了冰连接状态的新捕获(浏览器仅在状态变为“失败”时关闭连接):
很有趣的是,这次,会议进行了整整18分钟。该操作是在星期六的早晨进行的,因此我猜测该问题可能与twilio服务器上的当前工作负载有关。但是,它失败的方式与迄今为止对我而言始终一样。另外,我们甚至有一个有效的过时随机数响应,该响应已由firefox正确处理。
但是,如果我们对同一捕获采取不同的看法,则可以看到流量在Firefox认为连接被丢弃并发送生命周期为零的Refresh请求之前,停止中继30秒钟。与以前的捕获一样,服务器以“分配不匹配”错误进行响应,表明它不知道firefox在谈论哪个分配。
最后发送的八个数据包大小相同,所以我猜测它们是重传。重传30秒后,SCTP可能会将传输视为已丢弃。
关于生命周期为零的刷新请求,我做了一个测试,我从浏览器中尽早关闭了连接。在这种情况下,服务器会识别分配并返回成功响应:
分配不匹配是最容易观察到的症状,但是在我的本机应用程序测试中,我看到非零生存期的Refresh请求和CreatePermission请求(438“ Wrong nonce”错误)发生了类似的错误。但是,由于浏览器在30秒未中继数据后关闭了连接,因此在当前的webrtc演示中很难观察到这些错误。如果我们可以将超时时间更改为10分钟,那么我们也会看到这些错误。
答案 0 :(得分:3)
优秀的问题描述!
没有服务器日志,很难确定出了什么问题。我尝试了TURN.TURN服务器,该服务器运行最新版本的coturn,并表现出与Twilio服务器相同的行为。 Xirsys似乎正在运行coturn的自定义版本(软件领域的Coturn-0.5'Xirsys Turn Services',但coturn从来没有这样的版本)。
在两个捕获中,firefox都会检测到流量停止中继(在数据通道级别),并通过发送有效期为零的刷新请求数据包尝试正常断开连接。
不完全是。生命周期为0的刷新请求用于丢弃分配。此时,服务器返回什么都无所谓,因为连接还是无法修复的。
这是由于在绑定库版本中ice连接状态更改为断开连接here时,peerjs关闭了对等连接。
这过于激进(甚至无法解决问题),我们已经讨论了规范应如何尝试使用冰重启here来解决问题,该讨论也提供了很好的解释处于断开状态。
断开状态可能是由于丢失了一些数据包而发生的。但是,当拥塞较小时,可能会发生这种情况。我建议在断开连接的情况下删除pc.close()。
如果您正在寻找其他TURN提供商,Tokbox将提供same service。对于数据通道,正确运行的分布式TURN网络的延迟与VoIP无关紧要,因此您可以在单个位置运行自己的服务器。