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

2024-02-29

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

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

这里的限制因素是什么?

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

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


影响吞吐量的变量有很多,而且很大程度上取决于您测量吞吐量的方式。但我将列出一些我为提高 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。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

适用于高带宽应用的 WebRTC 数据通道 的相关文章

随机推荐

  • 限制 Node JS Express 中的 api 访问

    我有一个带有一些 API 路由的 Express 服务器 如下所示 server post api send email req res gt 您不需要身份验证令牌即可访问 API 但我只想要我的网站mydomain com才能使用它 我尝
  • 类型推断和借用与所有权转移

    我正在学习 Rust 并且遇到了一些令人困惑的行为 以下代码可以正常编译并按预期工作 edit 添加了测试函数以外的代码 之前省略 struct Container lt a gt contents a mut i32 fn main le
  • 将 IFORT 与 nvcc 和 CUSP 结合使用的未解决的引用

    我有一个正在编译的程序 如下所示 Some ifort f c nvcc c src bicgstab cu o bicgstab o I home ricardo apps cusp cusplibrary Some more for c
  • 计数排序的时间复杂度

    I am taking an algorithms course and there I saw that the time complexity of counting sort is O n k where k is the range
  • 出现错误 -->“任务执行失败”>NDK 未配置

    我正在尝试在 android studio 上编译我的代码 但我陷入了这一点 我没有任何东西可以使用 ndk 进行编译 但每次编译都会因此错误而失败 当我检查workspace xml时 它包含compileDebugNdk和compile
  • 如何在 swift 中为枚举添加更多案例

    我正在尝试在 Swift 中实现以下目标 向枚举添加更多案例 而不是编辑现有案例 例如 我有以下枚举 我想使用扩展添加更多案例 而不是在原始枚举上进行编辑 enum UIType String Codable case borderButt
  • canvas html5 中的透明度 context.fill 样式 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我写了这段 JavaScript 代码 context shadowOffsetX 5 context shadowOffsetY 5 co
  • 重复数组的每个值不同的时间

    Suppose a 0 1 0 2 0 3 0 4 0 5 0 6 and s 3 3 9 3 6 3 我正在寻找重复的最佳方式a i 确切地s i 次 然后有一个扁平数组 其形式为b 0 1 0 1 0 1 0 2 0 2 0 2 0 3
  • SSIS 包相对于 Windows 预定 exe 的优势

    我在Windows调度程序下配置了一个exe 用于对一组数据执行及时操作 该exe调用存储过程来检索数据并执行一些计算并将数据更新回不同的数据库 我想知道 使用 SSIS 包相对于预定的 exe 有什么优点和缺点 您的意思是使用 SQL S
  • 添加 UIImage 会忽略 UIImageView 框架并调整其大小

    我目前正在尝试将图像添加到一个视图的导航项中 在视图的viewDidLoad 使用以下代码调用函数 类似于这个帖子 https stackoverflow com questions 24803178 swift navigation ba
  • 虚拟主机无法使用 XAMPP 服务器创建

    我在 httpd vhost conf 文件中添加以下代码
  • 最新SDK的SDKROOT路径

    我正在使用 Xcode 构建旧代码并指定SDKROOT Developer SDKs MacOSX HOST VERSION sdk 我想为系统上预安装 的最新 SDK 指定 SDKROOT 例如我在10 8已经并且我想指定SDKROOT与
  • 未加权无向图中的最长路径

    以此图作为参考 假设我想要 0 到 5 之间的最长路径 那将是 0 gt 1 gt 3 gt 2 gt 4 gt 6 gt 5 有什么好的算法吗 我已经搜索过 但没有找到任何我能理解的东西 我发现了很多最短路径的算法 0 gt 1 gt 2
  • Python:Struct.pack(format, [...]),虽然格式几乎相同,但打包数据的大小不同

    import struct data struct pack ici 1 chr 1 1 print len data 12 data struct pack iic 1 1 chr 1 print len data 9 两个 data 变
  • 连接 MongoDB Atlas 与 Mongoose 时出现超时错误

    我正在尝试使用 mongoose 连接到 MongoDB Atlas 上的数据库 但每次它都会给我以下错误 node 2327 UnhandledPromiseRejectionWarning Error queryTxt ETIMEOUT
  • 密码和不同类型的加密

    我知道 我知道 类似的问题已经被问过数百万次了 但由于大多数问题都有不同的风格 所以我有自己的风格 目前我正在开发一个网站 该网站打算在全国范围内推出 因此需要对用户系统进行某种保护 我最近读了很多关于密码加密 散列 加盐 凡是你能想到的内
  • ios:使用 GLEssentials 示例代码显示简单的 3D 模型

    我的目标是显示一个简单的 3D 模型并在其上应用纹理 我已经下载了 GLEssentialsios示例项目 http developer apple com library ios samplecode GLEssentials Intro
  • 删除 SimpleForm 生成的选择字段的空白选项

    我有这段代码 f input category as gt select label gt false collection gt Choices Categories Choices Categories 只是 key gt value
  • 使用 TCP 的模拟器连接

    又嗨了 我正在尝试连接在同一台 PC 上作为服务器和客户端运行的两个模拟器 问题是其中一个位于虚拟机内 每个模拟器应该使用什么地址才能在它们之间进行连接 我正在使用基于 TCP 的连接 第一个模拟器在 Windows 7 上运行 Vmwar
  • 适用于高带宽应用的 WebRTC 数据通道

    我想通过 WebRTC 数据通道发送单向流数据 并且正在寻找最佳配置选项 高带宽 低延迟 抖动 以及其他人在此类应用程序中的预期比特率的经验 我的测试程序发送 2k 的块 使用 2k 的 bufferedAmountLowThreshold