每隔一段时间,我就会遇到一个人(或一个公司),出于某种未知的原因,决定在其WebRTC会话中使用TCP。我的意思是将 TURN/TCP 或 ICE-TCP 连接优先于其他一切,很多时候甚至禁止或忽视UDP的存在。随之而来的对话通常是漫长而艰巨的,而且恐怕并不总是富有成效。
所以我决定写这篇文章,解释为什么在大多数情况下,基于 UDP 的 WebRTC 远远优于基于 TCP 的 WebRTC。
UDP 和 TCP
自从互联网出现以来,我们就将 UDP 和 TCP 作为在网络上传输数据的底层传输协议。虽然还有其他传输方式,但这些是迄今为止最常见的传输方式。
他们在各个方面都彼此不同。
UDP 是传输协议可以提供的最低限度要求。(您可以得到比这更低的要求,但有什么意义呢?)
使用 UDP,您可以通过网络将数据包从一个点发送到另一个点。没有任何保证:
- 您的数据包可能会在途中“丢失”
- 他们可能会被重新排序
- 或重复
没有保证。我有没有提到这部分?
使用 TCP,您可以通过“连接”将数据流从一个点发送到另一个点。它附带了一切:
- 保证数据交付
- 数据按照发送的确切顺序接收
- 没有重复或其他类似的废话
这种保证交付需要有重传的概念,沿途丢失的东西需要重传。稍后会有更多关于这一事实的内容。
我们最终得到了同一连续体的两个极端,但我们需要选择一个或另一个。
TCP 统治网络
阅读此页?您正在通过 HTTPS 执行此操作。
HTTPS 通过 TLS 连接运行(我知道,有 HTTP/3 但请耐心等待)。
而 TLS 只是具有安全性的 TCP。
如果您改用 WebSocket,那么它也是 TCP(如果它是安全的 WebSocket,则为 TLS)。
无法回避这个事实,至少在 HTTP/3 变得普遍之前(这与在 TCP 之上运行略有不同,但那是另一篇文章)。
在 WebRTC 进入我们的生活之前,您在网络浏览器中所做的一切都以某种方式基于 TCP。
UDP rules VoIP
VoIP 或 IP 语音或 IP 视频或实时通信 (RTC) 或……好吧……WebRTC 通过 UDP 进行。
为什么?因为围绕保证交付的这件事对需要实时的东西的健康没有好处。
让我们假设网络上每个方向的延迟为 50 毫秒,这是相当不错的。这转化为 100 毫秒的往返时间。
如果一个数据包丢失了,那么至少需要100毫秒的时间,直到发送该数据包的人知道这一点–任何低于这个时间的都不会让接收者抱怨。通常情况下,它需要比100毫秒多一点的时间。
对于 VoIP,我们希望降低延迟。否则,通话听起来会不自然——人们会互相讲话过多(例如,在长途通话中时常发生)。这意味着我们不能真正等待这些重传发生。
这就是为什么VoIP,一般来说,特别是WebRTC,选择使用 UDP 来发送其媒体流。这里的概念是,等待将导致整个会话期间的延迟,完全降低了体验,而需要处理丢失的数据包,试图掩盖这一事实将在大多数情况下造成小问题。
对于WebRTC,你希望并且更愿意使用UDP来传输媒体信息,而不是TCP或TLS。
WebRTC ICE:偏好和尽力而为
我们并不总能得到我们想要的。这就是为什么有时我们的会话无法通过 UDP 使用 WebRTC 打开。不是因为我们不希望他们这样做,而是他们做不到,有什么东西阻止了我们的选择。
那个东西叫做防火墙。一个带有令人讨厌的规则……好吧……不允许 UDP 流量。原因多种多样:
- 30 年前,聪明的 IT 人员认为 UDP 不好,不能在互联网上使用,所以最好直接阻止它
- 另一个 IT 人员不喜欢工作的人在公司网络上下载最新的节目,所以他阻止了加密类型的 UDP 流量(本质上就是 WebRTC 媒体流量的样子)
这意味着您将需要 TCP 或 TLS 才能在该 WebRTC 会话上连接您的用户。
但是——这是一个很大的但是。您并不总是想使用 TCP 或 TLS。就在需要的时候。这将我们带到了ICE。
ICE 是一种程序,它使 WebRTC 能够通过进行连接检查来协商连接会话的最佳方式。
概括地说,我们将使用这种类型的逻辑(或努力这样做):
上图显示了我们在与 ICE 协商会话时的偏好类型。
- 我们喜欢使用直接 UDP
- 如果不可能,那么通过 TURN/UDP 服务器中继就可以了
- 那么直接TCP连接就好了
- 否则通过 TURN/TCP 或 TURN/TLS 服务器中继
UDP 排在第一位。
TCP(或 TLS)何时适用于 WebRTC 媒体?
使用 TCP 或 TLS 作为 WebRTC 媒体传输的唯一原因是因为 UDP 不可用。
是的。它值得在这里拥有自己的整个部分,因此您不会错过它。
当一切都失败了,TCP 对我来说是 WebRTC 的最后手段。
TCP 何时会打破 WebRTC 的媒体传输?
网络上出现数据包丢失的那一刻,TCP 就会中断。我所说的中断并不意味着连接会丢失,但您将体验到的媒体质量会比使用 UDP 时下降得更多。
拥塞造成的数据包丢失将是最严重的。为什么?因为它是由于数据路径上的交换机或路由器被阻塞并开始抛出需要处理的数据包而发生的。
以下是此时会出错的所有事情:
- TCP 将重新传输数据包——因为它们未被确认并被视为丢失
- 重新传输它们需要时间。我们没有的时间
- 对于视频流,丢包很可能会转化为对新 I 帧的请求
- 因此发送方将生成一个新的 I 帧,它比其他帧大
- 这反过来会导致更多数据通过网络发送
- 而且由于网络已经拥堵……这只会使情况变得更糟
- 不过,这是“不错”的事情。TCP 正在重传丢失的数据
- 所以我们现在有不需要通过网络发送的数据
- 已经很拥挤了。造成更多拥堵。对于我们无论如何都不会使用的东西
- 这实际上损害了我们发送接收方试图请求的 I 帧的能力
- 我们也在 TCP 之上运行,所以我们没有简单的方法知道东西正在丢失和重新传输,因为 TCP 隐藏了所有重要数据
- 所以我们知道 WebRTC 丢包的时间太晚了
- 无法使用像内部数据包延迟这样的逻辑
- 并且无法使用算法足够快地纠正拥塞和数据包丢失情况
如果您不相信我,请查看我们几年前在 testRTC 进行的测试,了解TURN/TCP 如何影响 WebRTC 流(有和没有丢包)。
底线——TCP 导致数据包丢失问题比实际情况更加恶化,与我们在 UDP 上运行相比,解决这些问题的余地要小得多。
最后,对于我们在WebRTC等协议中的实时通信要求,TCP对正在发送的数据所做的假设都是错误的。
原文链接:https://bloggeek.me/why-you-should-prefer-udp-over-tcp-for-your-webrtc-sessions/
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/16195.html