影响吞吐量的变量有很多,而且很大程度上取决于您测量吞吐量的方式。但我将列出一些我为提高 WebRTC 数据通道的吞吐量而调整的内容。
免责声明:我没有对 libwebrtc 进行这些调整,而是对我自己的 WebRTC 数据通道库进行了这些调整RAWRTC https://github.com/rawrtc/rawrtc,顺便说一句,它也可以为 Android 编译。然而,两者都使用相同的 SCTP 库,都使用一些 OpenSSL-ish 库和 UDP 套接字,因此所有这些都应该适用于 libwebrtc。
请注意,WebRTC 数据通道实现使用usrsctp https://github.com/sctplab/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 发送/接收缓冲区大小
libwebrtc 使用的 SCTP 堆栈 usrsctp 的默认发送/接收窗口大小,为 256 KiB https://github.com/sctplab/usrsctp/blob/master/Manual.md#usrsctp_sysctl_set_sctp_sendspace它太小了,无法以中等延迟实现高吞吐量。理论最大吞吐量受限于mbits = (window / (rtt_ms / 1000)) / 131072
。因此,默认窗口为window=262144
和相当适中的 RTTrtt_ms=20
,您最终将获得理论最大值 100 Mbit/s。
实际最大值低于该值...实际上,远低于理论最大值(参见我的测试结果 https://docs.google.com/spreadsheets/d/1Ze2hZl9KZJ1hKcm5Y9J0OIknQCBHUpw5eefskCc8xpM)。这可能是 usrsctp 堆栈中的错误(请参阅sctplab/usrsctp#245 https://github.com/sctplab/usrsctp/issues/245).
Firefox 中的缓冲区大小已增加(请参阅错误 1051685 https://bugzilla.mozilla.org/show_bug.cgi?id=1051685) 但在 Chrom(e|ium) 使用的 libwebrtc 中则不然。
发布版本
优化级别 3 有所不同(废话!)。
消息大小
您可能想要发送 256 KiB 大小的消息。
除非你需要支持Chrome?? (抱歉,我目前不知道它落在哪里...),那么最大消息大小为 64 KiB(请参阅问题 7774 https://bugs.chromium.org/p/webrtc/issues/detail?id=7774).
除非您还需要支持 Firefox 错误 979417).
它还取决于您在暂停发送之前发送了多少(即缓冲区的高水位线),并且当您在缓冲区耗尽后继续发送时(即缓冲区的低水位线)。我的测试表明,针对高水位线1 MiB 并设置低水位线256 KiB 可实现足够的吞吐量。
这减少了 API 调用的数量can增加吞吐量。
最终结果
在 RAWRTC 上使用默认设置的优化级别 3 使我的速度达到约 600 Mbit/s。
在此基础上,将 SCTP 和 UDP 缓冲区大小增加到 4 MiB,使我的速度进一步达到约 700 Mbit/s,其中一个 CPU 核心处于 100% 负载。
然而,我相信仍有改进的空间,但不太可能是轻而易举的事。
如何查看数据是否真正直接点对点传输,或者是否使用了 TURN 服务器?
Open about:webrtc
在火狐或chrome://webrtc-internals
在 Chrom(e|ium) 中并查找所选的 ICE 候选对。或者使用 Wireshark。