用于高带宽应用的 WebRTC 数据通道

标签 webrtc rtcdatachannel webrtc-android

我想通过 WebRTC 数据通道发送单向流数据,正在寻找最佳配置选项(高 BW、低延迟/抖动)以及其他人在此类应用程序中对预期比特率的体验。

我的测试程序发送 2k block ,带有 2k 的 bufferedAmountLowThreshold 事件回调并再次调用发送,直到 bufferedAmount 超过 16k。在 Chrome 中使用它,我在 LAN 上实现了 ~135Mbit/s,从/到远程连接实现了 ~20Mbit/s,两端都有 100Mbit/s WAN 连接。

这里的限制因素是什么?

如何查看数据是否真正直接点对点传输,或者是否使用了 TURN 服务器?

我的最终应用程序将使用 Android 上的 google-webrtc 库——我只使用 JS 进行原型(prototype)设计。我可以设置选项来加快库中的比特率,这是我在官方 JS API 中无法做到的吗?

最佳答案

影响吞吐量的变量有很多,而且很大程度上取决于您的测量方式。但我将列出我为提高 WebRTC 数据通道的吞吐量而进行的一些调整。

免责声明:我没有为 libwebrtc 做这些调整,而是为我自己的名为 RAWRTC 的 WebRTC 数据通道库做这些调整。 ,顺便说一句,它也为 Android 编译。然而,两者都在底层使用相同的 SCTP 库,都使用一些 OpenSSL-ish 库和 UDP 套接字,因此所有这些都应该适用于 libwebrtc。

请注意 WebRTC 数据通道实现使用 usrsctp在同一台机器上执行时通常受 CPU 限制,因此在测试时请记住这一点。使用 RAWRTC 的默认设置,我能够在我的 i7 5820k 上达到 ~520 Mbit/s。根据我自己的测试,Chrom(e|ium) 和 Firefox 都能够在默认设置下达到 ~350 Mbit/s。

好吧,让我们深入调整...

UDP 发送/接收缓冲区大小

默认情况下,Linux 中 UDP 套接字的默认发送/接收缓冲区非常小。如果可以,您可能需要对其进行调整。

DTLS 密码套件

大多数 Android 设备都有 ARM 处理器,但不支持硬件 AES。 ChaCha20 通常在软件中表现更好,因此您可能更喜欢它。

(这是 RAWRTC 默认协商的内容,所以我没有将其包含在最终结果中。)

SCTP 发送/接收缓冲区大小

usrsctp 的默认发送/接收窗口大小,libwebrtc 使用的 SCTP 堆栈,is 256 KiB这太小了,无法以适度的延迟实现高吞吐量。理论上的最大吞吐量受限于 mbits = (window/(rtt_ms/1000))/131072。因此,使用 window=262144 的默认窗口和相当适中的 rtt_ms=20 RTT,您最终将获得 100 Mbit/s 的理论最大值。

实际最大值低于此……实际上,远低于理论最大值(参见 my test results )。这可能是 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 调用量并且可以增加吞吐量。

最终结果

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

基于此,将 SCTP 和 UDP 缓冲区大小增加到 4 MiB 使我进一步提高到约 700 Mbit/s,一个 CPU 内核处于 100% 负载。

不过,我相信仍有改进的余地,但不太可能轻松实现。


How can I see if the data is truly going peer to peer directly, or whether a TURN server is used?

在 Firefox 中打开 about:webrtc 或在 Chrom(e|ium) 中打开 chrome://webrtc-internals 并查找所选的 ICE 候选对。或者使用 Wireshark。

关于用于高带宽应用的 WebRTC 数据通道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56327783/

相关文章:

javascript - 为二进制 block 创建元数据以通过 WebRTC 数据通道发送

webrtc - 创建通过 SCTP 而不是 RTP 发送数据的 DataChannel

android - 如何在原生 android 2019 中使用 WebRTC

Android WebRTC 实现 - 音量非常低

google-chrome - SessionDescription 为空。将 Chrome 更新到最新的 v 89 后,在 web rtc 中。使用以前的 Chrome 版本

javascript - 带有 WebRTC 和 UV4l 驱动程序的 Raspberry Pi Cam(源代码已关闭?)

webrtc - 创建 WebRTC PeerConnection 时,我可以跳过 ICE (STUN/TURN) 发现过程吗?

ios - WebRTC iOS : remote video is not shown in iOS client

javascript - 使用 webRTC 在两个对等点之间创建和使用数据通道

java - 在android中的webrtc中使用噪声抑制模块