作者:Pipe(原文链接)
翻译:刘通
原标题:Troubleshooting WebRTC Connection Issues
对称NAT后方的受限制网络,屏蔽端口,甚至应用层和传输层的协议屏蔽都可能造成WebRTC连接失败。我们将在本文中深入探讨WebRTC端到端连接建立这一个复杂的程序,并且会列出可能导致连接失败的过程。
建立一个WebRTC端到端连接需要3步:
#1 信令
#2 发现
#3 连接建立
上述三个步骤之中任何一步都有可能出现问题。
第一步:信令
信令是建立WebRTC端到端连接的第一步。信令是想要建立端到端连接的两方用来交换初始信息的通道。
建立初始阶段需要交换下面几个信息:
# 参与各方的IP及可使用的端口号(ICE候选)
# 媒体功能
# 会话控制消息
Websocket被广泛应用于信令中。像Kurento这样的著名的WebRTC媒体服务器在使用它们。如果你想要在信令过程中进行安全的数据传输,那么建议你使用安全websocket(wss://)。
信令也是WebRTC建立过程中,最先可能出现问题的地方之一。
以Kurento为例,Kurento在8888端口接收websocket连接,在8443端口接收安全websocket连接。这个默认配置允许Kurento在你的网页服务器上平行运行,但因为它们使用的不是像80或者443这样的惯用端口,所以那些处于受限网络的电脑或者设备,有很大的可能性并不能与你的信令服务器通过这些端口进行通信。
在端口80或者443上运行信令是你确保WebRTC高连接率所能做的第一件事。
一旦在WebRTC终端和信令服务器之间建立了信令连接之后,就可以进行信息交换了。
其中一个重要的信息就是公共IP和每个终端可以使用的端口。对于直接连入互联网的电脑来说,想要寻找到IP并不是一个问题,因为它(OS)知道自身的公共IP地址,并且可以很简单地通过浏览器查询到。但是这对于处于本地网络中(路由器后方)的电脑和设备来说就会成为一个问题,也包括通过3G/4G连入网络的移动设备,因为它们的IP是本地网络分配的IP地址。
这些设备只知道它们自己的本地网络IP,所以它们使用STUN协议来:
1 与STUN服务器进行通信,来找到它们网络的公共IP以及可到达的端口。
2 打穿一个双向的通道,通过网络路由器的隐性NAT功能。
此外,对称NAT后的设备只能与之前进行过连接的设备通信,所以还需要一个TURN服务器传输由一端发送的数据,因为另一端终端无法穿过对称NAT与我们的设备直接连接。
每个WebRTC端点都要询问STUN/TURN服务器它们自己的公共IP和可连接的端口是什么。一旦接受到一个响应,WebRTC终端就会通过信令通道发送一个数据对给对方。这个IP:端口号对被叫做ICE候选。
与STUN/TURN服务器的通信是第二个可能造成WebRTC连接失败的地方。我们已经遇到过3个可能造成失败的原因:
1 默认的STUN/TURN端口被屏蔽
2 所有UDP端口都被屏蔽
3 STUN/TURN协议被禁止使用
端口屏蔽
还记得我们建议通过端口80或者端口443建立信令连接吗?STUN和TURN有它们自己默认的端口(互不相同):
# 发送(或接听)STUN/TURN请求的默认端口为3478。
# 通过TLS发送(或接听)STURN/TURN的默认端口5349。
# 一些服务器,像Google的通用STUN服务器,使用其他端口,如19305和19307。
上述任何端口都可以被想要进行连接的两端之一所屏蔽。这些情况中,都无法连接到STUN/TURN服务器。
为了避免这些问题的发生,可以对STUN/TURN服务器使用惯用端口(443/80),但是UDP和协议屏蔽的问题还是没法解决。
UDP屏蔽
默认STUN/TURN消息通过UDP传输,意味防火墙不允许DNS询问机制使用53端口,也就不允许STUN/TURN消息通过防火墙。
幸运的是,STUN/TURN服务器还可以通过TCP进行连接,通过指定URL中的transport参数来实现:turn:myTurnServer.com?transport=tcp
意思基本是告诉WebRTC客户“对于TURN/STUN服务器,通过TCP连接而不是UDP”。你也可以指定udp或者tls。
STUN/TURN屏蔽
开发者可能遇到的一个更严重的情况是STUN/TURN协议消息同时被屏蔽。举个例子,我们已经发现Tunnel Bear VPN屏蔽了STUN/TURN数据包,因为即便你通过VPN连入网络它们也会暴露你的真实IP。在这种情况中,你除了让用户在进行WebRTC通话的时候关闭这类app以外并没有其他解决办法。
第三步:建立连接
在每个WebRTC终端知道了对方的ICE候选之后,就可以建立端到端连接了。
在一些WebRTC用例中,比如视频录制,终端会同时作为信令服务器和WebRTC终端。
每个用户都会通过UDP向另一个终端发送数据:
# 如果是直接发送给对方的,那么就可能将数据发送给0-65535之间任一端口
# 如果是发送给TURN服务器的,那么数据会发送给49152-65535之间的一个端口
没有一种方法可以控制这些端口,它们会在“发现”阶段中被分配并作为ICE候选的一部分。