前言
最近几天真的是全部忙碌在架设 WebRTC 的开源实现,想实现 Coturn + SignalMaster + WebRTC 这样的组合。在这几天,真的是走过了无数的坑。因为环境和不同博主的教程的原因,从云服务器换到本地主机,再从本地主机换回到服务器,同样的文件不同的人有不同的配置,真的是头都晕了,腰酸背痛,主要还是我太菜!
不过还好,最终踏平了所有的坑,看到系统成功跑起来的那一刻,真的是特别开心。
一、WebRTC
1.1 WebRTC 是什么
首先来瞅一眼 WebRTC 是什么。根据百度百科的定义:
WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持 网页浏览器 进行实时语音对话或视频对话的 API。
根据上面的定义我们可以知道,WebRTC 本质上就是一个 API。
1.2 WebRTC 的发展局限
那么只要实现这样的 API,我们就可以实现在网页浏览器上进行实时语音或者视频对话。WebRTC 采用独特的端到端媒体流,其中语音、视频和数据连接都直接在两个浏览器或 WebRTC 应用之间建立。但是,由于存在网络地址转换(NAT)和防火墙,增加了这一技术的实施难度,需要采用特殊的协议和过程才能实现。
于是就出现了下面这几个协议:
- STUN:Session Traversal Utilities for NAT(RFC 5389)
- TURN:Traversal Using Relays around NAT(RFC 5766)
- ICE:Interactive Connectivity Establishment(RFC 5245)
- SDP:Session Description Protocol(RFC 4566)
1.3 NAT 地址转换
为了解决 IPV4 地址不够使用的问题,出现了 NAT 技术。NAT 的原理就是给一个 NAT 设备分配一个公网 IP 地址,NAT 设备背后的节点都将被分配私网 IP 地址,这样几十上百台节点只需要占用一个公网 IP 即可。那么对端如果只知道目标节点的公网 IP,将信息发到 NAT 设备中,那么 NAT 设备又是如何将信息发送到对应的节点的呢?
我们知道:通过 IP + 端口号
可以唯一的标识一个节点。在 NAT 设备中有一个地址映射表,这个表将公网的 IP + 端口号
的组合映射到了私网的 IP + 端口号
,如此就实现了内网穿透。
但是,现实的情况是:并不是每一个地址穿透都是成功的,在有些时候可能因为映射关系的外网数据包被丢弃了等其他一些复杂的原因,是无法实现成功穿透内网的。于是就相继出现了 STUN、TURN、ICE。
1.4 STUN、TURN、ICE 协议
STUN 是一种客户端/服务器协议,允许内网的主机向外网的 STUN 服务器查询自己的公网 IP 和端口号。可以将 STUN 理解为一面照妖镜,内网主机可以通过这面镜子看到自己的真实信息(公网 IP + 端口号)。这些信息被用来在两个同时处于 NAT 路由器之后的主机之间创建 UDP 通信。
TURN 协议是对 STUN 协议的扩展,用于在 STUN 穿透失败的时候,提供媒体中继。其背后原理是:TURN Server 是一个具有公网 IP 的节点,发送端的主机是肯定可以直接找到公网中的节点并发送数据给它的,TURN Server 在收到发送端的数据后,会缓存发送给接收端。
ICE 协议是 STUN 协议和 TURN 协议的结合,它利用 STUN 协议和 TURN 协议实现建立 P2P。
其通过定期发送数据包来提供长连接功能:
- 刷新ANT转换表有效期;
- 探测对端是否存在。
1.5 SDP协议
SDP 全称是 Session Description Protocol,翻译过来就是描述会话的协议。它主要用于两个会话实体之间的媒体协商。
SDP 是纯粹的会话的描述格式而不是一个传输协议。它可以使用不同的传输协议,包括会话通知协议(SAP)、会话初始协议(SIP)、实时流协议(RTSP)、MIME 扩展协议的电子邮件以及超文本传输协议(HTTP)。SDP 并不描述广播地址的分配或者详细的消息描述,并且SDP也不是为沟通媒体编解码而设计的。
SDP的目的是传送多媒体会话中的媒体流的信息,以使会话描述的接收者可以参加会话。所以,SDP应该包含足够的信息来发起会话或使接收者加入会话。
SDP 应该包含:
- 会话名和会话目的
- 会话激活的时间
- 会话由何种媒体组成
- 接收这些媒体的信息(地址,端口,格式等等)
- 会话所用到的带宽信息。
- 连接信息
1.6 信令机制
WebRTC 没有实现信令机制,使得程序可以更加灵活,我们可以根据自己的需求自定义信令。信令有多种实现方式,可以使用已有信令,比如 SIP,也可以通过自定义实现信令,比如通过 WebSocket 实现信令机制。