webrtc系列之-像老鼠一样打洞

众所周知,本光头刚涉猎音视频不久,所以很多东西都是边学边做的,有说得不对的地方,请各位多包涵。

说穿透之前,我们首先需要明白关于WEBRTC的一些概念,WEBRTC它是一个支持在browser实现实时音视频通信的一组技术框架,它是一组标准协议,它为开发者,用户提供了视频通信的核心技术,包括采集,编解码,网络传输,渲染等功能,并且是跨平台的。

 

webrtc是基于P2P的,即点对点通信,与传统的方式有什么不同呢?

(1) 传统的方式以服务器为中介

(2) P2P的连接在数据通道形成的时候,中间是不经过服务器端的

 

采用P2P的优点是可以减轻服务器压力,但是真的不需要服务器端吗?

这其实是一个走偏了的想法,webrtc仅仅是不需要服务器中转数据。但有两件事情则必须要走服务器端的。

(1)  浏览器之间交换信令

(2)  NAT穿透和防火墙

关于信令交换,并不在本篇的重点介绍当中,简单说一下就是A和B需要建立P2P连接,这时候则需要中间服务器(信令服务器)作协调,也需要中间服务器告诉另一端P2P连接断开状态。这些用来控制连接的状态的数据一般称之为信令,而这个与服务端连接的通道,就是信令通道。

 

关于NAT穿透,则是本章的重点内容,也就是像老鼠一样打洞。NAT是一组网络地址转换的协议,NAT的技术特点会引发外网地址的访问,这时修候就得采用NAT穿透了。

 

NAT技术(Network Address Translation,网络地址转换)是一种把内部网络(简称为内网)私有IP地址转换为外部网络(简称为外网)公共IP地址的技术,它使得一定范围内的多台主机只利用一个公共IP地址连接到外网,可以在很大程度上缓解了公网IP地址紧缺的问题。

 

有哪些不需要用NAT穿透的?

(1)  位于同一个私网内,可以直接通过内网IP地址通信

(2)  通信双方都有独立的公网IP地址,可以直接通过公网IP地址通信。

 

在我们的现实的应用环境中,大多数设备都是位于NAT之后,比如连着同一个基站的移动设备,同一个小区的宽带用户等,NAT的存在使得设备间不能直接进行点对点的通信。这时候我们就需要用到NAT穿透技术,这是为了解决使用了NAT后的私有网络中设备间建立连接的问题,常见的NAT穿透技术方法主要有:

应用层网关;

中间件技术;

打洞技术(Hole Punching);

Relay(服务器中转)技术。

 

我们在WEBRTC开发的过程中一般是使用ICE进行NAT穿透。

ICE是一组穿透方法而不是协议,它融合了STUN和TURN,ICE使得两个NAT后设备通信更加便捷,ICE使用STUN进行打洞,若失败,则使用TURN进行中转。

STUN:NAT会话穿透应用程序,它是基于UDP的解决方案,属于打洞技术 ,STUN是一种CS协议,也是一种Request/Response的协议,默认端口号为3478,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的公网端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间创建UDP通信。

四种主要NAT类型中有三种是可以使用STUN进行穿透:完全圆锥型NAT、受限圆锥型NAT和端口受限圆锥型NAT,对称型NAT则不能使用。

TURN:通过Relay方式穿透NAT,是一种数据传输协议,它是允许通过TCP或UDP方式进行穿透,它也是一个CS协议,与STUN类似 ,都是通过取得应用层中的公网地址达到NAT穿透。但实现TURN client的终端必须在通讯开始前与TURN server进行交互,并要求TURN server产生"relay port",也就是relayed-transport-address。这时TURN server会建立peer,即远端端点(remote endpoints),开始进行中继(relay)的动作,TURN client利用relay port将数据传送至peer,再由peer转传到另一方的TURN client。

TURN主要用在使用STUN无法穿透的场景下,例如前面说到的对称型NAT,只能通过TURN server进行数据中转。

 

我们假设jerry和tom要进行通信,这两个位于NAT之后,公网部署了STUN与TURN服务器。

首先客户端要收集候选地址(candidate),这数据结构由IP地址和端口号组成 ,收集的candidate要与对方的candidate组成成对的candidate pair,进行连通性检查。主要有三种:

(1) host candidate:从本地网卡获取的地址

(2) server reflexive candidate (srflx): stun server观察的该client的地址

(3) relay reflexive candidate(relay): turn server为该client分配的中继地址。

client通过向stun服务器发送stun数据包,stun服务器做出回应告知其在数据包中监测到的IP地址以及端口。

 

连通性检查

收集candidate后把通过信令offer与answer方式双方交换candidate,进行candidate两两配对,然后ICE连通性检查。这个连通性检查按一定规则的。

本地的candidate与远端candidate构成的每一对都有一定的优先级,按优先级排序进行连通性检查。

 

数据传输

最后从有效的candidate组合中选择优先级最高的作为传输地址,用于数据传输。

 

Trickle ICE

在WebRTC中使用ICE框架进行P2P通信。前面说到ICE中第一步是收集candidate,需要遍历STUN以及TURN服务器,这一步需要耗费很多时间,导致双方建立通信时间很慢。为了解决这一问题,WebRTC引入了Trickle ICE,这样candidate收集以及连通性检查可以同时进行,加快双方建立通信的速度。

 

libnice库

若要让我们的程序支持ICE,我们可以借助第三方库。常见的支持ICE的库有Libjingle,Libnice。Libjingle集成在WebRTC里,不方便独立使用,这里我们推荐使用Libnice,常见的WebRTC服务器,例如janus,licode都是使用libnice进行P2P通信,具体可访问Libnice官网了解。

 

看,是不是很复杂? 光头还是往简单了的说的,如果是一步步去搭建架构,估计没有一个星期是搞不定的。实际上我们在快速开发中有许多开源框架可以使用,帮助我们去实现各种各样的需求。

下一次本光头要为大家介绍如何快速搭建实时音视频通讯的系统架构。敬请留意哦。

posted on 2021-07-08 17:06  睿江云  阅读(477)  评论(0编辑  收藏  举报