1. WebRTC

WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准。

它由一组标准、协议和JavaScript API组成,用于实现浏览器之间(端到端)的音频、视频及数据共享。

WebRTC使得实时通信变成一种标准功能,任何Web应用都无需借助第三方插件和专有软件,而是通过简单地JavaScript API即可完成。


2. WebRTC标准和开发

Web Real-Time Communications (WEBRTC) W3C Working Group是负责定义浏览器接口部分标准的组织 Real-Time Communication in Web-browsers (RTCWEB) 是 IETF 工作组,负责定义协议,数据格式,安全,以及一切技术底层。

https://hpbn.co/webrtc/

https://www.w3.org/TR/webrtc/#simple-peer-to-peer-example

  • MediaStream:获取音频和视频流
  • RTCPeerConnection:音频和视频数据通信
  • RTCDataChannel:任意应用数据通信


3. WebRTC分层 RTCPeerConnection

分层协议图

ICE、STUN和TURN是通过UDP建立并维护端到端连接所必需的;SDP 是一种数据格式,用于端到端连接时协商参数;DTLS用于保障传输数据的安全;SCTP和SRTP属于应用层协议,用于在UDP之上提供不同流的多路复用、拥塞和流量控制,以及部分可靠的交付和其他服务。

DTLS对TLS协议进行了扩展,为每条握手记录明确添加了偏移字段和序号,这样就满足了有序交付的条件,也能让大记录可以被分段成多个分组并在另一端再进行组装。

DTLS握手记录严格按照TLS协议规定的顺序传输,顺序不对就报错。最后,DTLS还要处理丢包问题:两端都是用计时器,如果预定时间没有收到应答,就重传握手记录。

为保证过程完整,两端都要生成自己签名的证书,然后按照常规的TLS握手协议走。但这样的证书不能用于验证身份,因为没有要验证的信任链。

SRTP为通过IP网络交付音频和视频定义了标准的分组格式。SRTP本身并不对传输数据的及时性、可靠性或数据恢复提供任何保证机制,它只负责把数字化的音频采样和视频帧用一些元数据封装起来,以辅助接收方处理这些流。

SCTP是一个传输层协议,直接在IP协议上运行,这一点跟TCP和UDP类似。不过在WebRTC这里,SCTP是在一个安全的DTLS信道中运行,而这个信道又运行在UDP之上。

由于WebRTC支持通过DataChannel API在端与端之间传输任意应用数据,而DataChannel就依赖于SCTP。


3.1 ICE(Interactive Connectivity Establishment,交互连接建立)

ICE跟STUN和TURN不一样,ICE不是一种协议,而是一个框架(Framework),它整合了STUN和TURN。

由于端与端之间存在多层防火墙和NAT设备阻隔,因此我们需要一种机制来收集两端之间公共线路的IP,而ICE则是干这件事的好帮手。

  • ICE代理向操作系统查询本地IP地址
  • 如果配置了STUN服务器,ICE代理会查询外部STUN服务器,以取得本地端的公共IP和端口
  • 如果配置了TURN服务器,ICE则会将TURN服务器作为一个候选项,当端到端的连接失败,数据将通过指定的中间设备转发。

例

如上图所示,如果A想与B通信,那么其过程如下:

  1. A收集所有的IP地址,并找出其中可以从STUN服务器和TURN服务器收到流量的地址;
  2. A向STUN服务器发送一份地址列表,然后按照排序的地址列表向B发送启动信息,目的是实现节点间的通信;
  3. B向启动信息中的每一个地址发送一条STUN请求;
  4. A将第一条接收到的STUN请求的回复信息发送给B;
  5. B接到STUN回复后,从中找出那些可在A和B之间实现通信的地址;
  6. 利用列表中的排序列最高的地址进一步的设备间通信。

由于该技术是建立在多种NAT穿透协议的基础之上,并且提供了一个统一的框架,所以ICE具备了所有这些技术的优点,同时还避免了任何单个协议可能存在的缺陷。因此,ICE可以实现在未知网络拓扑结构中实现的设备互连,而且不需要进行对手配置。另外,由于该技术不需要为VoIP流量手动打开防火墙,所以也不会产生潜在的安全隐患。

3.2 NET

网络地址转换协议Network Address Translation (NAT) 用来给你的(私网)设备映射一个公网的IP地址的协议。一般情况下,路由器的WAN口有一个公网IP,所有连接这个路由器LAN口的设备会分配一个私有网段的IP地址(例如192.168.1.3)。私网设备的IP被映射成路由器的公网IP和唯一的端口,通过这种方式不需要为每一个私网设备分配不同的公网IP,但是依然能被外网设备发现。

一些路由器严格地限定了部分私网设备的对外连接。这种情况下,即使STUN服务器识别了该私网设备的公网IP和端口的映射,依然无法和这个私网设备建立连接。这种情况下就需要转向TURN协议。

3.3 STUN(Session Traversal Utilities for NAT)

STUN即NAT会话穿透实用工具[RFC5389],用于进行NAT穿透,采用的是典型的客户端/服务端模式。客户端发送请求,服务端进行响应。

STUN是一个允许位于NAT后的客户端找出自己的公网地址,判断出路由器阻止直连的限制方法的协议。

客户端通过给公网的STUN服务器发送请求获得自己的公网地址信息,以及是否能够被(穿过路由器)访问。

STUN

STUN是一个C/S架构的协议,支持两种传输类型。一种是请求/响应类型,由客户端给服务端发送请求并等待服务端响应;另一种是指示类型,由服务器或者客户端发送指示,另一方不产生响应。两种类型的传输都包含一个96位的随机数作为事务ID(transaction ID),对于请求/响应类型,事务ID允许客户端将响应和产生响应的请求连接起来;对于指示类型,事务ID通常作为debugging aid使用。

STUN报文和大多数网络类型的格式一样,是以大端编码(big-endian)的,即最高有效位在左边。所有的STUN报文都以20字节(160位)的头部开始,后面跟着若干个属性。

3.4 TURN(Traversal Using Replays around NAT)

TURN的全称为Traversal Using Relays around NAT,是STUN/RFC5389的一个拓展,主要添加了Relay功能。如果终端在NAT之后,那么在特定的情景下,有可能使得终端无法和其对等端(peer)进行直接的通信,这时就需要公网的服务器作为一个中继,对来往的数据进行转发。这个转发的协议就被定义为TURN。TURN和其他中继协议的不同之处在于,它允许客户端使用同一个中继地址(relay address)与多个不同的peer进行通信。

如果TURN使用于ICE协议中,relay地址会作为一个候选,由ICE在多个候选中进行评估,选取最合适的通讯地址。一般来说中继的优先级都是最低的。TURN协议被设计为ICE协议(Interactive Connectivity Establishment)的一部分,而且也强烈建议用户在他们的程序里使用ICE,但是也可以独立于ICE的运行。值得一提的是,TURN协议本身是STUN的一个拓展,因此绝大部分TURN报文都是STUN类型的,作为STUN的一个拓展,TURN增加了新的方法(method)和属性(attribute)。

TURN

3.5 SDP

会话描述协议Session Description Protocol (SDP) 是一个描述多媒体连接内容的协议,例如分辨率,格式,编码,加密算法等。所以在数据传输时两端都能够理解彼此的数据。本质上,这些描述内容的元数据并不是媒体流本身。

从技术上讲,SDP并不是一个真正的协议,而是一种数据格式,用于描述在设备之间共享媒体的连接。

记录SDP远远超出了本文档的范围。但是,这里有几件事值得注意。