哦,你用的是 Google STUN server 啊,我以为你是在 STUN server 部署中遇到问题了。
ICE 我也没有部署过,只知道原理。两个 web media client 之间的网络拓扑结构是什么样的?可以首先尝试局域网内的两个客户端通信,如果这都不工作,说明是配置问题。然后再在双方在不同 NAT 后面的环境中测试,能不能穿透 NAT 就听天由命了。
所谓的穿透 NAT,或称 UDP 打洞,是基于这样一个观察:大多数 NAT 实现在选取公共 IP 上的源端口时并非随机,对相同的内部 IP 和内部端口组合,不论目的 IP 和端口是什么,所选取的公共 IP 上的源端口很有可能是相同的。
在 RFC 5245 中,欲发起通信的两个客户端会从自己的网络配置获取自己的私有 IP 和端口,从 STUN server 尝试获取自己的公共 IP 和端口,并把这些信息通过中转服务器(如 web application)告诉对方。两个客户端分别首先尝试直接连接对方的私有 IP 和端口,如果不成功再尝试连接对方的公共 IP 和端口。每个客户端连接的时候要始终使用相同的源 IP 和源端口组合。
如果双方可以直连,则直连成功。如果双方只有一方在 NAT 后,在 NAT 后的直连成功,在公网的使用对方公共 IP 连接也成功。如果双方都是在符合上述观察的 NAT 后,则直连都不成功,使用对方公共 IP 连接至少有一个会成功,这就建立了 UDP 连接。为什么至少有一个会成功呢?假设 A 首先发起连接,会在 A 的 NAT 表中记录下 A、B 的公共 IP 和端口(所谓五元组),但这个包到达 B 的 NAT 会被丢掉。B 接下来发起连接时,根据假设,会在 B 的 NAT 表内记录下 B、A 的公共 IP 和端口(五元组),这个包到达 A 的 NAT 时匹配上五元组,发送给 A。A 此后的回复到达 B 的 NAT 时也匹配上五元组,发送给 B。也就是只有第一个包被牺牲了。当然,如果 A 和 B 几乎同时发起公共 IP 连接尝试,则包到达对方前对方的 NAT 中已经有相应五元组,则双方的连接尝试都会成功。