WebRTC通话最典型的应用场景应该是一对一视频通话,如微信视频,QQ视频等。我们回想一下日常生活中是怎么进行“实时音视频”交流的,假设A与B要进行面对面说话,通常A会说:B,xxx,向B发出“问候”声明,表明我要和你开始对话了,你方便嘛。这时候,如果B正在和C说话,可能就会说:稍等,我和C聊完再和你说。如果B带了降噪耳机,可能只是收到了A的信号,还没听清楚具体的意思,那么可能就会说:再说一遍,刚刚没听清楚。也有可能B心情不好,没有理睬A的话语。情况很多,甚至B是外国人,可能会回复:dsl#%¥……*&。在实时音视频建立的过程,就和现实中A和B建立沟通的过程一样,情况非常复杂,可能B在内网,还有防火墙,可能B是APP端,可能B用的是Edge,chrome甚至IE。这里我们在后续博客中说明webRTC是怎么解决这些问题的。 我们先简化这个流程,把最主要的步骤提取出来,如图所示:
第一步:媒体协商
Peer A与Peer B通过信令服务器进行媒体协商,比如决定双方使用的音视频编码格式,对比两个人在真实世界交流,肯定会选择一个两个人都懂的语言一样。双方交换的媒体数据由sdp,即 session description protocol(会话管理协议)描述。那么如果一个中国人,一个外国人,中国人不懂英语,外国人不懂中文怎么办,这时候,就需要“翻译”出场了。翻译的作用不用多说,有他的存在就意味着,就算A不懂B的编码,B也不懂A的编码,双方也能通过“翻译”进行交流。在WebRTC中,“翻译”就是双方都能访问的服务器,来帮助交换连接所需要的信息。有了交换数据的中间人后,两个客户端首先要交换的就是SDP,这里就描述了最关键的双方要建立怎样的连接。
两个客户端都需要了解对方支持的媒体格式,比如Peer A支持VP8,H264,Peer B支持VP9,H264等,要保证两端都能正确的编码解码,最简单的就是取两个的交集h264.所以这个过程就叫做媒体协商。而SDP从哪里来呢,一般是连接双方先通过API来制定自己要传输什么样的数据,如Audio,video,datachanner以及自己希望接受什么样的数据,然后Peer A调用CreateOffer()方法,获取offer类型的SessionDescription通过公共服务器传递给Peer B,同样,Peer B通过调用CreateAnswer(),获取answer类型的SessionDescription通过公共服务器传递给Peer A,在这个过程中,由哪一方创建Offer都可以,但是要保证连接双方创建的SessionDescription类型是相互对应的。整个交换过程如图所示:
信令服务器可以用来交换双方的SDP信息,一般是通过创建Socket连接进行交互处理,可以使用java,golang,node等技术,只要能交换到双方的SDP数据即可。
从技术上讲,SDP并不是一个真正的协议,而是一种数据格式,用于描述在设备之间共享媒体的连接。SDP包含的内容非常多,比如版本,会话名,会话起始时间,结束见,音频传输和datachannel是否公用同一个传输通道等百来个字段。
第二步 网络协商。Peer A与Peer B通过STUN服务器获取到各自的网络信息,如IP和端口,然后通过信令服务器转发,互相交换各种网络信息。这样双方就知道对方的IP和端口了,即P2P建立直接连接。这个过程就涉及了NAT以及ICE协议,后面也会对这些协议进行说明。当然,理想情况下,每个浏览器所在的计算机都是公网IP,这意味着都可以进行点对点进行连接。但是实际情况是我们的计算机都是在某个局域网中并且有防火墙,比如公司的电脑,自己的手机,家里的电脑等,想要进行两台设备的连接,就需要进行网络地址转换,即 Network Address Traslation,NAT。如图所示:
至于为什么局域网就不能用公网IP,其实原因是IPv4下地址匮乏而出现的技术。通常我们都会连接路由器,路由器分配的地址通常是192.168.1.1,如果有n个设备,通常就是192.168.8.n,而这个地址显然是内网地址,这样一个路由器的公网地址对应了n个内网地址,这样就能缓解ip地址空间的枯竭。同时,NAT技术会保护内网地址的安全性,但是当进行P2P的连接方式时,NAT会组织外网地址的访问,这时就需要NAT穿透技术了。
所以有了以下思路:借助一个公网IP服务器,Peer A与 Peer B都往公网IP发包,公网服务器就可以货值peer A与Peer B的Ip,又由于Peer A与Peer B主动给公网ip服务器发包,所以公网服务器可以穿透NAT A与NAT B,并发送给Peer A,Peer B。在WebRTC中采用ICE狂叫来保证RTCPEerConnection能实现NAT穿透。
而ICE,interactive connectivity establishment,互动式连接建立是一种框架,使各种NAT穿透技术,如STUN,TURN可以实现统一,该技术可以让客户端成功的穿透远程用户与网络之间可能存在的各类防火墙。
STUN是指简单的UDP穿透NAT,这项技术运行位于NAT后的客户端找出自己的公网IP地址,以及查出自己位于哪种类型的NAT以及NAT所绑定的internet接口。这些信息可用于将两个同时处于NAT罗油漆之后的主机建立UDP通信。
不过即使通过STUN服务器取得了公网ip地址,也不一定能建立连接。因为不同的NAT类型处理传入的UDP分组的方式是不同的,四种主要类型中有三种可以使用STUN穿透:完全圆锥形NAT,受限圆锥形NAT和端口受限圆锥形NAT。但大型公司网络中经常使用的对称型NAT则不能使用,这类路由器会透过NAT部署所谓的Symmetric NAT限制,也就是路由器只会接受之前连接过的节点所建立的连线,这类网络就需要用到turn技术。
turn是中继穿透NAT,traversal using relays around nat,是STUN的一个扩展,主要添加了中继功能。如果终端在进行NAT后,在特定的情境下有可能使得终端无法和其他终端进行直接的通信,这时就需要将公网的服务器作为一个中继,对来往的数据进行转发,这个转发采用的协议就是TURN。
前面提到的信令服务器一般搭建在公网或者至少两端都可以访问到的局域网,借助信令服务器,就可以实现SDP以及Candidate交换。不仅如此,信令服务器还能进行房间管理,用户列表,用户进入/退出等IM功能。
第三步 建立连接。Peer A和Peer B如果没有建立连接,则通过TURN中转服务器转发音视频数据,最终完成音视频通话。建立连接的流程大致步骤如下:
[if !supportLists]1.[endif]连接双方通过第三方服务器交换 signaling各自的sdp数据。
[if !supportLists]2.[endif]连接双方通过STUN协议从STUN服务器那里获取自己的NAT结构,子网ip和公网ip,端口等信息。
[if !supportLists]3.[endif]连接双方通过第三方服务器交换各自的cadidate,如果连接双方在同一个NAT之下,那它们仅通过内网Candidate就能建立起连接。如果他们处于不同的NAT下,就需要通过STUN服务器识别出公网Candidate进行通信。
[if !supportLists]4.[endif]如果仅通过STUN无法建立连接,则需要寻求TURN服务器提供转发服务;
到了这里,整个流程就清楚了,这样一抽象,WebRTC这个名词至少是懂了,离“实时音视频”这五个字稍微深入了一点。那么后续,就将通过实际的代码,来演示整个过程,最后通过一个小项目,完成一对一的视频。
最后,附上WebRTC的官网,几乎所有的资料都可以在上面找到:
感谢阅读!
联系邮箱:shentupenghui@qq.com
日期:2020.1129
@杭州
有疑问加站长微信联系(非本文作者)