【发布时间】:2019-01-18 11:58:42
【问题描述】:
我使用Twilio Network Traversal Service 作为本机应用程序的一部分我是working on 来执行对等远程桌面连接。我们实现了 WebRTC 协议栈的一个子集,它等效于 WebRTC 数据通道(不是 WebRTC 视频和音频协议)。使用 TURN 中继时,TURN 分配似乎在会话开始后几分钟到最多 12 分钟之间随机失效。这个问题看起来与one 非常相似,但在我的情况下,建议的解决方法(发送无声音频)是不可接受的,因为我没有实现 WebRTC 音频/视频协议。
在过去的两周里,我一直在努力解决这个问题,并将问题隔离为 Twilio 服务本身。为了比较,我使用了一个基于 Web 的 WebRTC 数据通道演示,它使用了 firefox 和 Xirsys TURN server cloud。我有wireshark捕获显示firefox与Twilio断开连接,就像我的本机应用程序一样,而完全相同的firefox演示在使用Xirsys服务器时没有断开连接。
我最初使用的是 Xirsys,但我在他们的服务中遇到了一些不稳定性,这让我改用了 Twilio,这就是为什么我宁愿让 Twilio 解决这个问题而不是回到 Xirsys。至少,我宁愿有两个 WebRTC 托管服务提供商可供我选择,我知道它们应该可以正常工作。这就是为什么我要花时间详细解释这个问题以便解决它。
这是两个使用 WebRTC 数据通道和 Twilio TURN 中继服务器的 Wireshark 捕获(过滤掉对等数据消息)显示 firefox:
在第一次捕获 4 分钟后,流量停止中继,在第二次捕获大约 11 分钟后。在这两个捕获中,firefox 检测到流量停止中继(在数据通道级别),并通过发送一个生命周期为零的刷新请求数据包来尝试正常断开连接。两次正常断开都会导致 437 Allocation Mismatch 错误,表明服务器甚至不知道 firefox 正在尝试正常关闭的分配。
对于我的本机应用程序,这通常会采用 CreatePermission Request 消息的形式,该消息失败并出现 438“Wrong nonce”错误,这基本上是客户端尝试更新不再分配的权限时应该发生的情况存在。错误代码 438 通常表示“Stale nonce”,这并不是真正的错误,而是表明 nonce 已过期,客户端应使用“错误”消息中包含的新 nonce 重试。我花了一段时间才弄清楚,但即使错误代码是438,错误字符串也不一样。我在 Xirsys 中观察到一个真正过时的 nonce 错误,并使用错误响应中的新 nonce 成功更新了我的权限,所以我知道我可以在我的实施中正确处理这种情况。
这里是我使用的 WebRTC 数据通道演示的源代码: https://github.com/devolutions/webrtc-demo
为了比较,这里是使用 Xirsys TURN 服务器云的相同 firefox 数据通道演示:
在这个捕获中,我让演示运行了大约 16 分钟(它的运行时间比这要长得多,我尝试过的最长时间是两个小时)。我们可以看到流量在整个会话期间不断中继,并且 CreatePermission 请求不断被 firefox 成功发送。最后,优雅断开是由 Firefox 关闭 WebRTC 数据通道触发的(而不是由于流量不再被中继而被关闭)。与 Twilio 捕获相反,生命周期为零的 Refresh 请求是成功的:Xirsys TURN 服务器仍然知道分配并按预期发回成功响应。
应该注意,ICMP 不可达错误是正常的,因为我认为在这种情况下,当响应返回时,firefox 不再监听给定端口。换句话说,它发送生命周期为零的刷新请求,并且不等待回复返回。
目前,我别无选择,只能返回 Xirsys,但我非常希望 Twilio 网络遍历服务能够修复。如果您对此问题有更多疑问,请告诉我。
我已经上传了wireshark捕获here供参考。
编辑:我修改了 webrtc 演示页面,使其在 ice 连接状态设置为“断开连接”时不会关闭连接。现在,当冰连接状态变为“失败”时,我得到了真正的断开连接。然而,它实际上并没有改变任何东西,因为在这种情况下,状态从“断开连接”变为“失败”只需要几秒钟。
由于我有新的相关屏幕截图和捕获,我正在更新原始问题以澄清 Philipp Hancke 指出的某些问题:
首先,这里是一个带有ice连接状态修复的新捕获(浏览器仅在状态变为“失败”时关闭连接):
有趣的是,这次会话持续了整整 18 分钟。这是在星期六早上拍摄的,所以我猜这个问题可能与 twilio 服务器上的当前工作负载有关。然而,它失败的方式与迄今为止对我来说总是一样的方式失败了。作为奖励,我们甚至有一个有效的、过时的随机数响应,可以被 firefox 正确处理。
但是,如果我们对同一捕获采取不同的看法,我们可以看到流量在 30 秒内停止中继,然后 firefox 认为连接已被丢弃并发送生命周期为零的刷新请求。与之前的捕获一样,服务器响应分配不匹配错误,表明它不知道 firefox 正在谈论哪个分配。
最后发送的八个数据包大小相同,所以我猜测它们是重传。重传 30 秒后,SCTP 可能会认为传输已被丢弃。
关于生命周期为零的刷新请求,我做了一个测试,我很早就从浏览器关闭了连接。在这种情况下,服务器识别分配并返回成功响应:
分配不匹配是最容易观察到的症状,但在我使用本机应用程序进行的测试中,我发现非零生命周期的刷新请求和 CreatePermission 请求(438“错误随机数”错误)有类似的错误。但是,由于浏览器在 30 秒没有中继数据后关闭连接,因此在当前的 webrtc 演示中很难观察到这些错误。如果我们可以将该超时更改为 10 分钟,我们也会看到这些错误。
【问题讨论】:
-
多么好的问题?!!!!!