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