如何创建一个视频聊天应用

Joshua Phua 原作,授权 New Frontend 翻译。

常见的视频应用利用了一种叫做 WebRTC 的技术。WebRTC 让开发者能够基于 web 交换数据和媒体文件的应用,可以用于大家日常使用的浏览器。这是近十年来发生的技术转变,过去只能通过 flash 之类的插件实现这一功能。

即使你没听说过 WebRTC,你多半已经用过它了。Whatapps、Facebook、Google handout 等都用了 WebRTC。WebRTC 是 Web Real-Time Communications 的简称,可以直接连接浏览器。这项技术已经存在了至少 7 年,但我终于赶上了! 我成功创建了自己的 WebRTC 应用,通过亲手实践来更好地理解 WebRTC 这一工具。

这是我的新玩具,亲手创建的 WebRTC 应用程序:web.phuaxueyong.com

本文会讨论一些比较宽泛的话题:

1. WebRTC 如何工作?

魔法其实并不神奇,只是背后隐藏的大量工作。就像鸭子一样,看上去只是在水面上优雅地游弋。但水面之下却是频繁地划动。

2. 运行 WebRTC 应用需要哪些组件?

Web 应用程序有不同的组件。大多数看不见、摸不着,比如服务器。但它们就像汽车发动机,开车的时候看不到(除非你开的是一辆道奇 Charger R/T),但这并不意味着发动机不存在。

道奇 Charger

3. STUN 服务器的作用是什么?

这一节会简单讲下 STUN 服务器的工作细节(整个通讯过程中哪个阶段需要 STUN 服务器,STUN 服务器如何工作)。

4. TURN 服务器的作用是什么?

这一节会讲什么时候需要 TURN 服务器。不是所有情况下都需要使用 TURN 服务器,不过在一些无法直接连接的场合需要使用这个组件。

5. 不同使用场景下 WebRTC 的架构选择及优化空间

WebRTC 主要有 4 种架构。你用 zoom 的时候有没有好奇过一台服务器如何处理 160 个成员参加的会议?这里没有魔法,实际上这需要传输大量数据,10 分钟的视频传输的数据可能需要以 TB 为单位计量。

选取适合业务用例的架构意味着已经成功了一半。

6. 如何测试 WebRTC 以及可供尝试的一些免费资源

摆弄我的新玩具的时候,我找到了值得一试的一些工具和资源,可以用在简单 WebRTC 应用的不同组件上。

让我们开动吧!

1. WebRTC 如何工作?

开始视频聊天会话时,首先需要向房间发信号,表示已经到了。告知其他人已经到了称为信令(Signalling)。如果你是第一个到的人,从技术上讲,你仍然会打招呼,不过没人回应而已。

用术语说,信令是交互式连接创建框架(Interactive Connectivity Establishment Framework)的一部分,是通过交换媒体信息来相互查找、协调通讯的过程。信令基于会话描述协议(SDP)收集网络信息,包括用于交换媒体的 IP 地址和端口。

会话描述协议(Session Description Protocol,SDP)是用来宣布、管理会话邀请的标准方法。它以文本格式表示浏览器的功能和偏好设置。

浏览器连接其他客户端时,通过 SDP 交换的信息包括:

  • 开启、关闭通讯的会话控制信息。
  • 错误信息。
  • 媒体元数据,比如编解码器及其设置、带宽和媒体类型。
  • 密钥数据,用于建立安全连接。
  • 网络数据,比如公网 IP 和端口。

WebRTC 应用架构

2. 运行 WebRTC 应用需要哪些组件?

1. 你需要一个用户界面

需要有个 web 应用,在页面加载或点击按钮时建立连接,接着显示聊天室成员发送的视频数据。

用术语说,需要创建 RTCPeerConnection,并发送给远程的聊天室成员,保存在他们的机器上。web 应用开发完毕后,需要托管在 web 服务器上,以供其他聊天室成员访问。

2. 你需要一个信令服务器

还记得我们之前提到的信令吗?它用来向某一特定聊天室的所有成员表示你已经就位。当你进入聊天室时,已经加入聊天室的每个成员都会通过 SDP 协议记录你的远程信息和细节,并将这些信息保存到他们的机器上——准备接收你的媒体数据。

技术上说,WebRTC 负责 SDP 信息的创建和处理,但不负责发送和接收 SDP 信息。因此,需要一个服务器来传输 SDP 信息。通常会用 websocket 服务器完成连接初始化和传输。

3. 你需要一个 STUN 服务器

这个服务器用于获取远程成员的公网 IP。为了避免过多涉及一些技术细节,我们假设每个成员都有一个公网 IP 供 STUN 服务器获取。这些信息会作为 SDP 信息的一部分在你加入聊天室时发送给聊天室成员。

4. 你可能需要一个 TURN 服务器

成员之间可能无法直接建立连接,因此需要 TURN 服务器作为一个中间人转发消息。参见 Quora 上的这个问答

3. STUN 服务器的作用是什么?

STUN 是 NAT 会话穿透应用程序(Session Traversal Utilities for NAT)的简称。通讯双方都需要知道对方的 IP 地址和 UDP 端口。

不管用什么架构,我们总是需要一个信令服务器用于注册成员和表示在场,也需要一个 TURN 服务器穿透网络,并确保内网 IP 可以映射到公网 IP。

参见 STUN 的工作机制 一文。

STUN 如何工作

如你所见,浏览器向 STUN 服务器请求公网 IP 信息。这一过程隐于幕后,用户不会感知到。不过我学到的一点是永远不会有真正的魔法,幕后发生了很多事情。如果你想要了解魔法,那么你需要了解幕后的这些步骤。

4. TURN 服务器的作用是什么?

中继穿透 NAT(Traversal Using Relay NAT)是一种网络流量中继协议。有时通过 STUN 服务器能够成功获取远程成员的公网 IP,但是因为防火墙、NAT 等网络相关工具的原因,需要可以在公网访问到的 TURN 服务器进行中继。TURN 服务器有点像是传递消息的中间人。

TURN 服务器如何工作

5. 如何扩容?值得考虑的四种主要架构!

网状

在网状网络(Mesh)架构下,成员之间两两连接,比如一个电话会议有三个成员,每条消息都需要加密、传输两次。

转发

选择性转发单元(Selective Forwarding Unit,SFU)位于会话的中心,智能地中继媒体。假设共有 n 个客户端,每个客户端需要和 SFU 建立一条上行连接用于上传媒体数据,以及 n - 1 条下行链接用于接收其他客户端的媒体数据。虽然这种架构需要的总连接数是 n ** 2,但每个客户端只需建立一条加密的上行链接,这就减轻了设备本身的带宽压力,这对移动设备而言尤其重要(移动网络的上行带宽更小)。

转发需要 SFU 这类额外的服务器基础设施,不过 SFU 能够高效地处理任务。这是因为除非需要录制视频,SFU 不用解密数据包,也不用解码数据。

混合

这一架构需要一个多点控制单元(Multipoint Control Unit,MCU)在会话中充当强力的媒体混合器。每个客户端和 MCU 建立一个连接。不管总共有多少客户端,每个客户端都只需要处理一个向 MCU 发送数据并从 MCU 接收数据的双向连接。

和转发架构类似,发送媒体数据只需要加密、上传一次,不同的是接收媒体数据也需要下载和解密一次。这种方式对客户端而言最高效,但对服务器而言最低效。解包、解码、混合、编码、打包都在服务器上进行。服务器需要大量资源完成这么多实时操作。

混合架构适用于有大量活跃参与者的应用场景,比如虚拟教室,以及设备资源限制比较紧张的应用场景,比如设备的带宽很有限。这一架构下服务器的开销很大。

组合

顾名思义,组合使用多种架构,根据具体情况为参与者创建会话。

  • 简单的双方通话,采用网状架构,这一架构最简单,需要的服务器资源最少。
  • 小型群聊、直播、在线活动,采用转发架构。
  • 大型群聊、虚拟互动,混合架构值得考虑。

6. 如何使用 Testrtc 测试 WebRTC 应用?

WebRTC 应用比较容易发生规模问题,因为它需要处理大量数据。所以如果你打算给 WebRTC 应用扩容,首先要考虑的就是采用合适的架构,其次要考虑数据流量问题。

我进行的压力测试中,共有 500 个参与者,分为多个聊天室,每个聊天室有 5 个成员,应用只撑了 6.5 分钟。在不到 10 分钟的时间内,服务器实际传输了 52 GB 的上下行数据。

6b. 资源

开发实现自己的 WebRTC 应用时,你可以试用以下的免费 STUN 服务器:

免费 STUN 服务器

我找到了一个比较全面的讲解 WebRTC 应用工作机制的 YouTube 视频。有意思的是,我发现所有 YouTube 上 WebRTC 视频都是几年前的。WebRTC 已经有 7 年的历史了。我 Joshua 终于赶上了,希望文章有助于你了解这个古老的技术。(:

参考资料:

评论

Loading comments ...