WebRTC 信令交换与群聊实现

Posted by Miaocf on January 11, 2021

1.什么是 WebRTC

WebRTC,全称:(Web Real-Time Communication),是一个免费的开源工程。
Google 把 WebRTC 视为和 HTTP 一样,不仅仅是一种解决方案,而是一种标准。
使各种终端,包括 浏览器、原生应用等具备音视频通讯和即时通讯的能力。

1.1 webrtc术语

####Signaling channel(信令通道)

一种资源,使应用程序可以通过交换信令消息来发现,建立,控制和终止对等连接。信令消息是两个应用程序相互交换以建立对等连接的元数据。该元数据包括本地媒体信息,例如媒体编解码器和编解码器参数,以及两个应用程序可能相互连接以进行实时流传输的可能的网络候选路径。 PS:信令通道通常由信令服务器提供(或信令服务)

Peer(对等节点)

接入同一webrtc房间(逻辑划分的管理单元)的进行实时双向流传输的任何设备或应用程序

Session Traversal Utilities for NAT (STUN)

一种协议,用于发现您的公共地址(公网IP)并确定路由器中可能阻止与对等方直接连接的任何限制条件。 PS:Stun服务由STUN服务器提供

Traversal Using Relays around NAT (TURN)

通过打开与TURN服务器的连接并通过该服务器中继所有信息来绕过对称NAT限制的服务器。 PS:当P2P链接建立失败,仍需要保证功能可用,这里就需要TURN服务器对所有数据进行中继。建立relay模式的链接 PS: TURN服务由TURN服务器提供

Session Description Protocol (SDP)

一种描述连接的多媒体内容的标准,例如分辨率,格式,编解码器,加密等,以便一旦数据传输,两个对等方就可以相互理解。 PS:描述终端信息的规范。

SDP Offer

发起建立会话链接的SDP消息(主动发送方),生成会话描述以创建或修改会话。它描述了所需媒体通信的各个方面。 PS:比如想要和一个对等节点建立链接。首先就得告诉对端,自身终端信息(分辨率,格式,编解码器,加密),而为了描述自身终端信息产生SDP 就被称为SDP offer

SDP Answer

answer SDP由响应者响应邀约者发送的offer SDP。Answer主要包含终端协商结果(answer端终端信息)。例如,如果offer中的所有音频和视频流都被接受。

Interactive Connectivity Establishment (ICE)

一个允许您的Web浏览器(webrtc终端)与对等方连接的框架。

ICE Candidate(Candidate) 一种能与对等方用来通信的一种方法(方式)。

1.2 STUN TURN ICE如何工作

  • ClientA首先创建PeerConnection对象,然后打开本地音视频设备,将音视频数据封装成MediaStream添加到PeerConnection中。

  • ClientA调用PeerConnection的CreateOffer方法创建一个用于offer的SDP对象,SDP对象中保存当前音视频的相关参数。ClientA通过PeerConnection的SetLocalDescription方法将该SDP对象保存起来,并通过Signal服务器发送给ClientB。

  • ClientB接收到ClientA发送过的offer SDP对象,通过PeerConnection的SetRemoteDescription方法将其保存起来,并调用PeerConnection的CreateAnswer方法创建一个应答的SDP对象,通过PeerConnection的SetLocalDescription的方法保存该应答SDP对象并将它通过Signal服务器发送给ClientA。

  • ClientA接收到ClientB发送过来的应答SDP对象,将其通过PeerConnection的SetRemoteDescription方法保存起来。

  • 在SDP信息的offer/answer流程中,ClientA和ClientB已经根据SDP信息创建好相应的音频Channel和视频Channel并开启Candidate数据的收集,Candidate数据可以简单地理解成Client端的IP地址信息(本地IP地址、公网IP地址、Relay服务端分配的地址)。

  • 当ClientA收集到Candidate信息后,PeerConnection会通过OnIceCandidate接口给ClientA发送通知,ClientA将收到的Candidate信息通过Signal服务器发送给ClientB,ClientB通过PeerConnection的AddIceCandidate方法保存起来。同样的操作ClientB对ClientA再来一次。

这样ClientA和ClientB就已经建立了音视频传输的P2P通道,ClientB接收到ClientA传送过来的音视频流,会通过PeerConnection的OnAddStream回调接口返回一个标识ClientA端音视频流的MediaStream对象,在ClientB端渲染出来即可。同样操作也适应ClientB到ClientA的音视频流的传输。

2.安装接入

拿iOS来说,使用 webRTC 需要以下步骤:

2.1 接入 webRTC SDK

通过pods安装 webRTC sdk, 注意使用的是谷歌官方的 ‘GoogleWebRTC’ SDK
最新版本的 GoogleWebRTC SDK 需要 iOS 10.0以上,
因此工程需要设置为: iOS Deplopment Target 10.0

1
pod 'GoogleWebRTC'

2.2 工程设置

因为需要访问相机、麦克风等音视频设备,需要在工程中添加配置

info.plist 文件中添加

1
2
3
4
5
6
//访问相机
<key>NSCameraUsageDescription</key>
<string>访问相机和拍照功能</string>
//访问麦克风
<key>NSMicrophoneUsageDescription</key>
<string>打开麦克风发送语音</string>

如果想在应用进入后台时,继续保持通话,还需要添加

1
2
3
4
5
音视频通话要额外添加
<key>UIBackgroundModes</key>
	<array>
		<string>voip</string>
	</array>

这个版本的 SDK 并不支持 bitcode,因此还需要关闭 bitCode,
在这里是以开发SDK的形式接入webRTC,因此需要以下设置

1
2
Pods -> TARGETS -> XXX -> BuildSettings -> Build Options -> Enable Bitcode ->NO  
Pods -> TARGETS -> GoogleWebRTC -> BuildSettings -> Build Options -> Enable Bitcode ->NO

因为 视频通话使用 RTCMTLVideoView 渲染视频,其内部使用 Metal 图形接口来渲染图像,
该接口不支持ArmV7,因此需要在 valid Architecture 选项中 移除 arm v7指令集

3. 架构设计

  1. Factory 类:全局持有一个 RTCPeerConnectionFactory 类实例,管理本地 RTCVideoTrack,RTCAudioTrack,RTCVideoSource,RTCAudioSource,RTCCameraVideoCapturer等类的实例,以上类的实例都是全局唯一的。
  2. Device 类: 控制本地 摄像头的开/关,前后摄像头的切换,音频输出 扬声器和听筒的切换。
  3. RTCManager类: 负责管理所有 peer connection,包括生成、关闭、断线重连等功能
  4. RTCClient 类:由 RTCManager 管理,负责 一个 Peer connection 的所有事务,包括webrtc的事件回调、生成/接收SDP和ICE信息.
  5. RoomManager 类: 负责信令层的事务,管理通话事件.
  6. AVChatManager 类: 对外暴露的接口类。外部统一由此类访问 音视频通话功能

注意事项:webRTC 生成的很多对象需要由外部持有,否则生成后会自动释放。如 RTCVideoSourceRTCVideoTrack

事件集合:

4.群聊建立流程

因为 WebRTC 是 P2P 连接,如果需要多人同时通信的话,就需要建立复杂的连接关系。

如图,如果3个人通话,就需要建立 3条 P2P 连接,而4个人通话就需要 6 条P2P连接,5个人通话就需要 10条P2P连接。
如果是 N 个人通话(N >= 3),就需要 N(N-3)/2 + N 条连接。人数越多,需要建立的连接会呈O(n^2)的趋势增长。
因此,P2P方案并不适合多人通讯,考虑到 终端 带宽和计算能力,要想保持高质量的音视频通话,人数上限大概在 6 个左右(参考微信)。
超过6人 P2S 方案更适合。如果仅是音频通话的情况,那么 P2P 通话人数可以增加一个数量级(估计)。

接下来说一下,如何建立起 多人通话的流程,此处已 A B C D 4人通话为例:

4.1 P2P连接流程

假设 A 与 B建立连接. A 发起邀请等待 B 回复:

  1. B 接受后, Server 发送Accept信令给A

  2. A 接收到 ACCEPT信令后, 创建 PeerConnecton, 生成 OFFER, 返回给B,

  3. B接到OFFER后,创建与之对应的PeerConnecton,设置OFFER, 然后生成 ANSWER 返回给A.

  4. SDP 信息交换完毕后,交换ICE信息,连接完成.

4.2 多端 P2P 连接建立流程

假设 有 A B C D 四个客户端

  1. A 向 B C D 发起邀请。

  2. 假设 B C D 依次接受邀请,(无论是何种顺序,还是同时接受,这里都要串行处理)

  3. B 接受,同时给 A 发送 ACCEPT 信令。

  4. A 接到 B 发来的 ACCEPT 信令,A 发送 OFFER SDP 信息给B, B 返回 ANSWER SDP 给A, A B交换ICE信息,A B 连接完毕.

  5. C 接受, 同时给 A B 发送 ACCEPT 信令,A B 发送 OFFER SDP 信息给C, C 返回 ANSWER SDP 给A B, AC BC交换ICE信息,A B C 连接完毕.
  6. D 接受, 同时给 A B C发送 ACCEPT 信令,A B C发送 OFFER SDP 信息给D, D 返回 ANSWER SDP 给A B C, AD BD CD交换ICE信息,A B C D 连接完毕.

一次连接 对于邀请者来说,就算是发送一次 OFFER 和接到一次 ANSWER,对于被邀请者来说,就是接到 一次OFFER 和发送一次ANSWER. 一个PeerConnection 只能建立一次连接 不能建立两次连接(例如 不能重复的发送和接收同一个客户端的OFFER

5 断线重连 机制

假设 A B连接失败,A为主动发起对话的那方,

  • 主动发起邀请的那方,销毁原先的 PeerConnection,
  • 重新创建与B相对应的 Peer Connection,然后发送 OFFER SDP给 B,
  • B 收到 OFFER SDP 后,将B本地与A相对应的PeerConnection 销毁,
  • 创建新的Peer Connection 与A对应,设置 OFFER SDP 后,
  • 生成 ANSWER 返回给A,交换ICE 重新连接.

6. 连接状态展示

PC 间连接状态变化,通过onconnectionstatechange接口回调获得. 共6种状态,分别是:

“new”
“connecting”
“connected”
“disconnected”
“failed”
“closed”

连接状态变化后,给出相应的提示文案.

7.多媒体控制

多媒体控制
1.镜头反转
2.静音/关闭摄像头
3.扬声器选择(听筒/外放)
4.画面分辨率选择(一般,清晰,高清)

参考资料:

官方示例
Pods 安装
WebRTC 官网 WebRTC 入门教程
WebRTC入门教程
WebRTC 连接建立
webRET 工作方式

关于转载

知识共享许可协议

本作品采用知识共享署名 4.0 国际许可协议 进行许可。 转载时请注明原文链接。图片在使用时请保留图片中的全部内容,可适当缩放并在引用处附上图片所在的文章链接。