文章目录
一、WebRTC需要解决的问题
WebRTC是由google提出的的一个用于端到端实现p2p音视频通信的框架。比起其他的hls, http-flv等直播方案,webrtc在公网的条件中能够做到百毫秒级别的延迟,非常厉害。
WebRTC是一个集成了音视频通话中的多个应用的框架,主要是想尝试解决音视频通话中的一系列实时音视频应用问题,比如采集,编码,解码,前后处理,传输,缓冲,渲染,美颜,回声消除等等等等。
要实现p2p通信,最重要的一点就是必须让两个peer知道对方的公网ip地址。但是实际上ip地址的数量有限,我国很多设备基本都没有独立的公网IP,而是位于NAT之后,所以要实现P2P通信,必须要实现NAT穿透。说到NAT穿透,就会涉及到WebRTC中的几个概念。
二、ICE(Interactive Connectivity Establishment)
ice是一个p2p的连接框架,它目的在于确定可用于双端通信的传输地址对。
ICE 基本思想,每一个代理拥有多种可用于与对端通信的候选传输地址(TRANSPORT ADDRESSES,针对特定传输协议(一般为 UDP 协议)的 IP 地址和端口的组合),ICE 通过不断地尝试以确定真正可用的传输地址对;
可能可行的地址对有以下几种:
- 直接连接的网络接口上的传输地址.
- NAT 公共端的转义传输地址,即服务器反射地址(server reflexive).
- TURN 服务器上分配的传输地址,即转发地址(relayed address),中继地址.
在这里,呼叫需要交换两种信息,即候选地址和媒体信息。
候选地址用于建立网络连接,存储着和网络连接相关的参数;
媒体信息SDP用于描述在对等连接上传出的数据的信息,比如音频,视频和应用数据。
三、ICE的详细步骤
在这里,我们使用这张图来详细讲解ICE的所有步骤:
1. 收集候选传输地址
候选传输地址,指的是有可能可以用于接收媒体以建立对等连接的IP地址和端口,其必须要在呼叫的时候收集而不能提前收集。
候选传输地址的类型如下:
候选地址类型 | 传达对端方式 | 用法 |
---|---|---|
主机候选地址 host candidate | 信令服务器 | 从网卡中获取到本地传输地址;若该地址位于NAT之后,则为私有地址,无法在子网之外路由到 |
信令服务器反射地址,SERVER REFLEXIVE CANDIDATE | 信令服务器 | 从发送给 STUN 服务器的 STUN 检查中获取的传输地址,若该地址位于 NAT 之后,则为最外层 NAT 的公共 IP 地址; |
对端反射地址,PEER REFLEXIVE CANDIDATES | Stun Binding 请求 | 从其他 ICE 代理发送的 STUN 连接检查中获取的传输地址,该地址是一种在连接检查期间发送的新候选项,不通过信令通道发送; |
对端反射地址,PEER REFLEXIVE CANDIDATES | Stun Binding 请求 | 从其他 ICE 代理发送的 STUN 连接检查中获取的传输地址,该地址是一种在连接检查期间发送的新候选项,不通过信令通道发送; |
中继地址,RELAYED CANDIDATES | 信令服务器 | 媒体中继服务器的传输地址,通过 TURN 分配请求获取; |
候选地址之间的关系如下图所示:
在图1中,主机A和主机B可以收集到的候选地址信息是:
2. 交换候选传输地址
通过信令交换候选传输地址,一旦收到候选传输地址,便对这些候选传输地址进行排序和确定优先级,一般主机候选传输地址优先级最高,其次是反射传输地址,最后是中继传输地址。
webrtc概念:轨道(track),常见有视频轨,音频轨,而要发送一条轨道中的数据,最多可能使用两个通道,分别是RTP和RTCP。
ICE代理使用P2PTransportChannel管理通道上的网络传输;一个P2PTransportChannel对应一条通道,若当前会话要同时处理音频,视频,每条轨道又都包括RTP,RTCP两种,则当前会话中存在4个P2PTransportChannel对象;P2PTransportChannel维护一张连接状态表来管理网络传输,表中每一条记录都对应一个connect对象。
实例讲解
比如在图1中主机A收到主机B发来的B$Cand1之后,P2PTransportChannel会向连接状态表新增两条记录,即两个connection。
当A收到了B的所有B C a n d 1 、 B Cand1、B Cand1、BCand2、B$Cand3 之后,状态表中的数据如下
检查连接
在交换完候选传输地址之后,下一步就是连接检查。
对于主机A当从主机B收到了SDP应答之后,便开始连接检查;对于主机B当向主机A发送了SDP应答的时候,便开始连接检查,每一个检查是一个STUN请求/响应事务,该事务通过客户端使用特定的候选地址对,由本地候选地址向远端的候选地址发送STUN请求/响应的方式执行,整个过程可以被概括为下图所示:
候选地址对状态变化如下图所示:
实例讲解
在状态表中新建一条记录,即一个connection,很快就会在此connection上进行stun检查,stun检查的具体操作是在此connection上发送一个stun binding请求,检查的步骤如下图所示:
我们可以看到,在STUN Binding中,同时发现了一个PEER REFLEXIVE CANDIDATES(对端反射地址,具体请参考上文的表一)。
- 若 A 和 STUN 服务器之间连接状态不好,在 A 收到 B 发来的 srflx(11.92.14.8)之后还没得出本身的 srflx(211.161.240.181);虽然 A 没得到自身的 srflx,但并不妨碍对 B 的 srflx 候选地址进行 STUN 检查,于是会向 11.92.14.8 发 STUN 请求;B 收到这个请求,从请求解析出 211.161.240.181,虽然该地址在值上等于 A 的 srflx,但不是从信令服务器得到,而是来自对端的 STUN 请求,此时 B 就会以这个 prflx 向状态表新建 Connection;【注意SR Candidate地址和PR Candidate地址的区别,SR Candidate地址是通过信令服务器发送的地址,而PR Candidate地址是在STUN Binding检查中解析得到的地址。】
2.A 在之后从 STUN 服务器确认了自身的 srflx,并通过信令服务器发向 B;B 发现该 srflx 值对应的 Connection 已存在,便不会重复创建连接;
选择特定的候选地址对并且启动媒体
连接检查将一直持续直到所有可能的检查都已经完成(所有的检查状态从“冻结”到“成功”/“失败”)或某一候选地址对被选定;
选择候选地址对的操作由施控 ICE 代理执行;
当收到的 STUN 连接检查属性指示将使用某个候选地址对时,受控 ICE 代理便可知对端 ICE 代理已经选择该候选地址对,随后,受控 ICE 代理便回复连接检查,确认使用该候选地址对;
确认了候选地址对之后,便可以使用选定的候选地址对发送媒体数据
建立长连接
ICE框架会每隔15秒通过使用的候选传输地址发送链接检查,以确保NAT映射以及过滤规则不在媒体会话期间超时;这样当媒体暂停或者因为其他原因没有发送的情况下,仍然可以保证连接可以持续建立。
若媒体会话仍然处于活动状态,对端ICE代理会生成STUN响应,若本端ICE收到了此STUN响应则表明仍然可以继续发送媒体数据;若本端ICE没有收到STUN响应则应停止媒体流并且需要重启ICE。【检查连接是否存活】
ICE的重启
任何一端ICE代理检测到传输基地址发生变更,都会触发重新启动ICE的事件,该事件将导致ICE代理重新从第一步开始执行整个过程。