webrtc是一个优秀的跨平台实时音视频通信技术,是一个peer to peer的通信模式。在网络通信中,p2p通信必然会涉及到nat的穿透问题,webrt通过ICE技术来提供NAT穿透功能。ICE(Interactive Connectivity Establishment),它定义了一个技术,这个技术使用了stun/turn协议,它可以使得客户端能够发现自己的候选通信地址,这些候选地址包括本地地址、本机对应的公网地址、中继服务器的地址,两个客户端通过信令服务器来交换这些候选地址,就可以实现点对点的通信/中继通信。
为了测试webrtc的NAT穿透功能,必然得使用两个处于不同nat后的客户端来进行测试,平时家里面的网络或者公司的网络,就算有多个电脑那一般也是处于同一个nat后的主机,怎么配置另一个nat后的主机呢?弄一个路由器配置一个不同网段的网络这当然可以,我的方法是使用手机(使用4g网络) + pc + 云主机方式。下面是连接示意图:
需要提一点的就是,webrtc并没有提供android版的peerconnection_client,而是提供了一个AppRTCMobile.apk,这个app的功能比peerconnection_client功能强大得多了,不过感觉它很不稳定,动不动就崩溃,而且经常建立视频通话失败。虽然无法直接使用AppRTCMobile来进行测试,但通过阅读AppRTCMobile的源码,可以自己弄一个android版的peerconnection_client。
话不多说,先上两张图纪念下自己的劳动成果吧:
下面记录下测试过程的一些要点。
1.webrtc中设置IceServer.IceServer其实就是stun/turn服务器的地址,如果只设置stun服务器,则会收集到自己的公网地址,如果设置了turn服务器,则会收集到公网地址和中继地址。当两个客户端无法穿透nat进行点对点通信时(对称型nat),则采用relay地址进行通信。在CreatePeerConnection之前,可以设置stun/turn服务器的地址。
2.coturn服务器的配置。coturn服务器软件实现了stun/turn协议,其安装配置都比较简单,网上教程比较多。
3.手机(联通4G网络)是无法和PC端的peerconnection_client进行点对点通信的,很可能 联通网络是属于对称nat,这两个客户端进行视频通话是通过coturn中继来实现的。家里网络下的peerconnection_client和公司网络下的peerconnection_client进行测试则可以穿透nat,实现真正的点对点通信。
基于UDP的p2p通信,需要考虑到客户端所在网络的NAT类型,常见NAT类型有下面的4种:
1.全锥型(Full cone).内网主机C使用端口P向不同的公网主机通信时,都会被路由器映射成公网地址C1和端口P1,其它公网主机可以通过C1和P1与内网主机C进行通信,通信前不需要C曾往其发送过数据。
2.受限锥型(Restricted cone).也称为ip受限锥形,同1类型,不过只有内网主机C1往公网主机C2发送过数据,C2才能往C1发送数据,且C2可使用不同的端口来发送数据。
3.端口受限锥型(Port restricted cone).也称为端口受限锥形,同2类型,不过增加了端口限制,公网主机C2不能使用其它端口向内网主机C1发送数据。
4.对称型(Symmetric)。对称型NAT会为内网主机C到不同的目的地映射一个不同的公网地址C1和端口P1,公网主机只有收到过数据后,才能通过C1和P1向内网主机发送数据。这种类型的NAT是最难穿透的。
常见的都是3、4型nat。一直以为对称型nat无法穿透,其实这种说法并不准确。准确的来说是通信双方的nat类型是下列组合的则无法穿透,其它类型的组合都可以穿透:
a. 端口受限nat + 对称nat
b.对称nat + 对称nat.
stun协议流程。stun协议比较简单,不需要用户名和密码即可获取到自己的公网ip和端口,收到Binding success response就可以得到自己的公网ip和端口了:
turn协议流程。turn协议请求服务器分配中继地址的时候需要带上用户名和密码,请求成功就可以得到中继ip和端口了。流程如下: