WebRTC数据通道用于高带宽应用程序。

3
我想通过WebRTC数据通道发送单向流数据,并寻求最佳配置选项(高带宽,低延迟/抖动)以及他人在这种应用程序中预期的比特率方面的经验。
我的测试程序发送2k的块,具有2k的bufferedAmountLowThreshold事件回调,并再次调用send,直到bufferedAmount超过16k。在Chrome中使用此功能,在局域网上实现了约135Mbit/s,在远程连接的情况下从/到拥有100Mbit/s WAN连接的两端实现了约20Mbit/s。
这里的限制因素是什么?
我如何知道数据是否真正直接进行点对点通信,还是使用了TURN服务器?
我的终极应用程序将在Android上使用google-webrtc库 - 我只是使用JS进行原型设计。我可以设置选项以加快库中的比特率吗,而无法在官方JS API中执行此操作?
1个回答

12
有许多变量会影响吞吐量,它也高度取决于您如何测量它。但是我将列出一些我已经调整过的内容,以增加WebRTC数据通道的吞吐量。
免责声明:我没有为libwebrtc进行这些调整,而是为我的自己的WebRTC数据通道库RAWRTC进行的,顺便说一下,它也适用于Android编译。但是,两者都使用底层的SCTP库,都使用某些类似于OpenSSL的库和UDP套接字,因此所有这些都应该适用于libwebrtc。
请注意,使用usrsctp的WebRTC数据通道实现在同一台机器上执行时通常会受到CPU限制,因此在测试时请记住这一点。使用RAWRTC的默认设置,我能够在我的i7 5820k上实现约520 Mbit / s的速度。根据我的测试,Chrom(e | ium)和Firefox均能够使用默认设置实现约350 Mbit / s的速度。
好的,那么让我们深入了解一下调整...
UDP发送/接收缓冲区大小
Linux中UDP套接字的默认发送/接收缓冲区默认情况下相当小。如果可以的话,您可能需要进行调整。
DTLS密码套件
大多数Android设备具有没有硬件AES支持的ARM处理器。ChaCha20通常在软件中表现更好,因此您可能希望优先使用它。
(这是RAWRTC默认协商的内容,因此我没有将其包含在最终结果中。)
SCTP发送/接收缓冲区大小
默认的usrsctp发送/接收窗口大小,即libwebrtc使用的SCTP堆栈,为256 KiB,这太小了,无法在中等延迟下实现高吞吐量。理论最大吞吐量受mbits = (window / (rtt_ms / 1000)) / 131072限制。因此,使用默认窗口window=262144和相当中等的RTTrtt_ms=20,您将得到理论最大速率为100 Mbit/s。

实际最大速率低于理论最大速率...实际上比理论最大速率要低得多(请参阅我的测试结果)。这可能是usrsctp堆栈中的错误(请参阅sctplab/usrsctp#245)。

Firefox已增加缓冲区大小(请参阅bug 1051685),但Chrom(e|ium)使用的libwebrtc没有。

发布版本

优化级别3会有所不同(傻瓜!)。

消息大小

您可能希望发送大小为256 KiB的消息。

除非您需要支持Chrome < ???(抱歉,我目前不知道它落在哪里...),否则最大消息大小为64 KiB(请参见issue 7774)。

除非您还需要支持Firefox < 56,在这种情况下,最大消息大小为16 KiB(请参见bug 979417)。

这还取决于在暂停发送之前发送了多少内容(即缓冲区的高水位标记),以及在缓冲区被排空后何时继续发送(即缓冲区的低水位标记)。我的测试表明,将高水位标记定为1 MiB并设置低水位标记为256 KiB可以获得足够的吞吐量。

这减少了API调用的数量,可能增加了吞吐量。

最终结果

使用默认设置的优化级别3在RAWRTC上使我的速度提高到了约600 Mbit/s。

基于此,将SCTP和UDP缓冲区大小增加到4 MiB进一步提高了我的速度,达到了约700 Mbit/s,其中一个CPU核心负载为100%。

但是,我认为仍然有改进的空间,但不太可能很容易实现。


如何查看数据是否直接进行点对点传输,或是否使用TURN服务器?
在Firefox中打开 about:webrtc ,或在Chrom(e | ium)中打开 chrome:// webrtc-internals ,并查找所选的ICE候选对。或者使用Wireshark。

嗨Lennart, 感谢您详细的回答。对于我们来说,使用RAWRTC似乎是更好的选择。与浏览器的兼容性对我们来说并不是必需的 - 就API和通道选项而言,最好的选择是什么?我只熟悉WebRTC API,ORTC似乎被分成了多个工具。使用ORTC的完整连接过程是什么? - jensk
1
ORTC只是另一种较低级别的API,如果您不需要WebRTC支持,那么我会使用ORTC。然而,数据通道API绝对相同。对于连接过程,请查看RAWRTC代码库中的[一个示例工具](https://github.com/rawrtc/rawrtc/blob/master/tools/data-channel-sctp-echo.c)。基本上,您需要交换参数并在每个传输上调用*start*。 - Lennart Grahl
从技术上讲,如果一个节点对不同的节点打开多个数据通道,那么该节点是否能够实现更高的吞吐量?(假设usrsctp吞吐量限制适用于每个数据通道,而不是整个系统)。 - user482594

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接