# 说在前面
本文涉及 WebRTC 最基础的部分,最终实现直播的类似效果。预计后面会和 Electron 系列文章合并。
# 相关资源
- MDN 上的 WebRTC
- html5rocks 上的 WebRTC
- 信令服务器
- coturn 服务器
- SocketIO
# 本篇内容
展示 WebRTC 的连接过程、搭建信令服务器、编译 coturn 服务器
# 关于 WebRTC
WebRTC 是谷歌推出的一项十分复杂的音视频项目,包含了网络通信、音视频处理、STUN/TURN 技术等。尽管内核技术很多,但是给出的 API 相当丰富且实用。
WebRTC 最大的特点在于只依靠浏览器就可实现通信,且由于基于 UDP 所以通信延时很短(0.5s-1s)并且抗弱网络性能很强,十分适合用在音视频连麦这种应用场景上。并且由于使用 STUN 技术,一旦连接成功,将不需要中间服务器,能有效降低媒体服务器的开销。
WebRTC 是个十分庞大的工程,本人能力不够无法从源码层面学习,只能通过简易的 JavaScript 接口来体验这一技术带来的体验。
# 简易关系图

- 图中省略了 NAT
- 信令服务器作为两端没有建立连接前的交流媒介
- 一旦通过交换令牌最终建立了连接,便不再需要信令服务器
- 两端实际上是对等的,没有主次之分,A 可以给 B 传递音视频,B 也可以给 A 传递音视频。不过这个可以从编程方面人工规定
# 信令服务器
双方一般都在 NAT 后,无法直接通信,而是需要一个具有公网 IP 的服务器作为双方交流的中继,此时这个服务器被称为 信令服务器 。
信令服务器的责任就在于交换双方的 offer、answer 以及 candidate,只要能实现这一流程的都可以叫做信令服务器,所以实现的技术并没有限制。从需要主动推送消息这一要求来看,是 WebSocket 类技术比较适合,为降低实现难度,选择二级封装的 SocketIO 作为核心通信技术
# 信令服务器代码 (Node.js)
1 | const { createServer } = require("http"); |
# 说明
- 不可避免的会发生跨域问题,代码中也解决了这个问题,有关更详细的回答请见 SocketIO 官方文档
- 代码中实现了一对一的 Offer、Answer 以及令牌的交换
运行起来之后就实现了信令服务器的搭建
# STUN/TURN 服务器
STUN 以及 TURN 都是穿越 NAT 的技术(协议),STUN 一旦连接成功将不需要中转服务器但会受到 NAT 类型的限制(大部分时候是可以的)而 TURN 技术则是依赖中转服务器进行数据交换,几乎没有失败的可能但是受限于中转服务器的带宽。二者各有利弊,WebRTC 提供了两种服务器的配置,当 STUN 无法打洞成功时,将会启用 TURN 连接以保证能够正常连接。
- 协议本身过于复杂,不建议手动构建。
- WebRTC 使用的 STUN 协议:RFC 8489 TURN 协议:RFC 8656
- 详细聊请见第三篇文章
# coturn 穿透服务器
coturn是一款开源服务器,实现了 STUN 以及 TURN 服务器以及 ICE 信令交换系统,并提供了 WebUI。- 安装配置参考其他大佬文章 https://www.jianshu.com/p/59ba50b5f71d
- Windows 用户可以下载这份我编译好的
# 验证穿透服务器是否搭建成功
验证网址
- 验证 STUN 服务器时,只需要填写第一栏:
stun:域名 - 验证 TURN 服务器时,需要三栏都填:
turn:域名coturn 配置中的用户名与密码 - 点击下方的
Add Server - 之后点击下方的
Gather candidates即可![file]()
只要图中出现了srflx与relay即可视为搭建成功
# 对等连接建立过程

# JS
# 通用 SocketIO 初始化、事件分发
1 | import io from "../node_modules/socket.io-client/dist/socket.io.esm.min.js"; |
# 服务端
1 | const streamButton = document.querySelector('#stream') |
# 客户端
1 | connection.on('offer', data => { |
# html
# 服务端
1 |
|
# 客户端
1 |
|
# 执行步骤
- 使用服务器之类的运行起网页,比如 VScode 的 Live Server 等
- 客户端与服务端使用不同的用户名登录
- 客户端填入服务端的用户名,点击 Call 发起通信
- 按 F12 打开两者控制台,查看终端输出
# 效果

- 可以看到两端互相传递了信息,当视频信息传输时会产生令牌

