一:ICE了解
(一)ICE简介
ICE的全称Interactive Connectivity Establishment(互动式连接建立),由IETF的MMUSIC工作组开发出来的,它所提供的是一种框架,使各种NAT穿透技术可以实现统一。
ICE跟STUN和TURN不一样,ICE不是一种协议,而是一个框架(Framework),它整合了STUN和TURN。
(二)ICE框架
框架图如下:其中所有的服务Relay Server与STUN Server都可以部署到同一服务器上
1.组成成员
第一个是双方通信的Peer 有两台机子A和B ,他们都是在NAT之后,并且这两个终端都会在NAT后面形成一个映射后的公网的IP地址。
这里有两个NAT,在NAT外面有两个STUN 服务(其实也可以用一个STUN服务),这里的STUN服务主要用于Peer终端去穿越NAT时候进行NAT穿越使用的(去判断NAT类型和获取终端在公网中的IP)。所以这两个可以是两个,也可以是一个,甚至可以是多个。
relay server,就是前面文章所介绍的这个TURN Server。这个relay server的实际大多数情况下也具有STUN Server的功能,所以在这里呢,有可能这三个是合成一个的。那他也可以获取到这个NAT映射后的这个公网IP,同时,它还有这个中继的功能。
那最后一个呢,是这个网络(最上侧,云图案,其实上面的TURN与STUN服务也是在网络中,都可以汇集在一个公网服务器中),整个这个信令是通过这个云端然后进行交互的,这就是他整个这张图包含了一些元素。
(三)ICE通讯流程
那我们就来看看这ICE是如何进行工作并且使这个两个终端最终进行这个媒体流的通讯的?(左侧peer---通信-->右侧peer),两侧终端都是有网卡(IP),可以进行通讯
让这个终端去得到所有能够连接到这个终端B的通路。那这个终端都有哪些通路呢?
1.内网直接通信
如果两个对端是在同一个局域网内,那么这俩就直接通过这个本地的IP地址就可以进行通讯。
2.穿越NAT
终端首先访问STUN服务,通过STUN服务,能获取到NAT映射后的终端的公网地址(IP+端口)。
并且终端双方可以通过服务器,获取得到对方的公网地址,就可以进行NAT穿越了!!
那如果穿越成功了,他们也直接就能通过NAT进行通讯了。
那么如果不成功,那么还有地方,那么第三条路呢,
3.TURN服务进行中继
就是走中继。那这个终端通过NAT将数据转给TURN中继,中继服务,再向另外一个端去转发数据。
那是不是就这三个呢?其实不是啊,在这个终端上其实可能是多网卡。所以有可能是四个,但是可能有那个VPN那就有五个,有可能是虚拟IP那六个。那一个其实每一个都要做一些尝试
4.ICE框架
所以ICE的基本的功能就是第一步,要收集终端双方所有的通路(因为终端可能包含多个网卡,必定包含多个通路),那么第二步就是对所有通路进行检测,看能不能通,那通了之后,那么ICE的这个工作就算结束了。
但一般情况下,经过relay,这是最后一条路的时候肯定会通的。
二:ICE基本概念
(一)ICE Candidate
获取到这些candidate之后,终端之间要交换这些candidate,那使用什么进行交换呢?----通过候选者对(双方各自取一个candidate,组成候选者对),形成通路(是否可以互通,还需要进行连通性检查)
是使用SDP,那么它是对于这个媒体信息以及网络信息的一个描述规范。
这个规范,最终是通过信令将这个SDP发送给对方,双方拿到各自的对方的SDP,那么就能识别出对方都有哪些通路,并且同时了解自己有哪些通路。
它的格式是什么呢?
就是A代表一个属性呢,属性是一个Candidate,就是一个候选者。在这个这个candidate里面必须包含一些基本信息,那第一个就是这个类型的,它是UDP的还是TCP的,他的IP地址是多少?端口是多少?
类型是什么?是主机类型(就是我们自己本机的这个网卡还是这个反射后的,经过NAT反射后地址还是中继地址,他是有类型的)。---见(二)
Candidate类型包含以下种类:(上面案例使用的是主机候选者)
主机候选者就是主机网卡的IP地址还有端口
反射候选者就是经过NAT之后的这个公网IP地址和端口(不是伪公网)
中继候选者就是通过TURN服务给开通的这个IP地址和端口
(二)ICE具体工作内容
1.实际刚才我们已经描述了那么第一个收集candidate,那怎么收集?刚才已经做了一些介绍,后面我们还会做更详细的。
2.那收集到这些这个候选者之后呢,其实他要做一下排序,不是说每个候选者就直接进行检测,这样会浪费很多时间。
形成候选者对之后哪条路跟哪条路,形成多组的候选者对之后呢,然后要根据一套算法进行排序,根据优先级最高的那个先做测试,因为有可能是先通的,这样就节省了时间。
3.那个最后呢,就是进行连通性测试,连通性测试就是尝试,终端发送一个请求,然后对端给终端回一个请求。OK,那么双方都收到了,这就连通的,如果说发出去之后超时了,没有收到,这就是说明是不连通的。
以上这就是ICE具体做的一些事情。
(三)Candidate的获取
那我们看一下这个candidate的关系图,也就是说我们如何拿到这个candidate的?
本地这是一个agent,实际就相当于我们一个终端,但本地网卡,网卡有IP,那这个就是host的类型的主机候选者。
经过NAT到那个TURN服务也可以到达STUN服务 ,一般情况下,像我们真实的这个配置的时候呢,是STUN服务和TURN服务是部署在同一台机子上的,程序同时具有STUN和TURN两者的功能。
因此,通过STUN服务,就可以拿到主机的映射地址,就是NAT之后那个映射的公网地址(IP和端口),也就是说是反射候选者。
此外,通过向TURN服务发送一个allocate请求,那么如果成功了,TURN服务端会开通中继地址(IP地址和端口),作为中继候选者。
所以这三种类型就是通过以上方式获取:通过发送一个请求获取这几种的候选者
主机候选者就是获取自己本机所有IP和指定端口。
发射候选者是通过向STUN/TURN服务发送请求的时候获取到的映射后的这个NAT转换后的公网IP和端口。
中继候选者是通过这个TURN服务,我们发送一个allocate的请求申请的这个服务,为数据的转发开通一个新的IP和端口,就是中继地址。
那么拿到这些候选者之后,我们要交换信息,刚才已经说了,就是通过SDP交换信息。
(四)SDP了解及基本格式
SDP案例: 下面这个例子中,就是一个标准的SDP案例
首先是版本信息v,一般都是0;
那第二个是o,表示为owner,这个SDP归谁所有,比如案例中主机名字jdoe,有多个系列号,最后包含一个IP地址。但是这IP地址并不一定是最终要进行传输的IP的地址,在我们WEBRTC里并不是用这个IP,而是使用candidate中的ip。
c表示connection表示连接这个网络的IPV4,OK,这些都不太重要。
那么这里呢,有一个媒体信息m,就是说在我这次交换媒体信息里,媒体就是一个audio也就是音频,它使用的是RTP的协议,
对于这个音频它有一个参数a=rtpmap,就是我使用的这个音频的编码方式是PCMU采样率是8000,这里大家了解一下就好。
最重要的是最后两行,它检测到有两种Candidate就是候选的路:
第一条是UDP的,IP 是 10.0.1.1端口是 8998,类型是host;
第二种也是UDP的,IP是192.0.2.3端口是45664,类型是穿越NAT的映射地址,
这里没有中继地址,就是最终不可能通过中继传输数据,那要么就是说我们在同一局域网内可以互通,要么就是穿越NAT走P2P,这就是SDP。
(五)Candidate Pair
获取得到所有的candidate之后,就要形成候选对,通过检测连通性之后,形成通路!!!
(六)连通性检测
获取得到所有的候选对之后,开始做连通性检测:
首先,要进行排序,要把优先级高的先排队最先进行检测,这样可以节省时间,这在之前已经做过介绍。
然后,那在检测的时候,首先是要进行发送检测,就是测试能不能发出去。如果可以发送出去的话,接下来进行接收检查。
最后,对每个候选对进行接收检查。
其实在实际过程中,为了节省时间,发送跟接收是串行的,所以如果发送出去之后,然后再能收回我自己发送的信息,那么说明整个通路就是通过了,这其实在实现时还是非常简单的,这么说起来呢,就是要分为发送检测和接收检测。