前面说了一下relay server, 其实它只是当客户端在某些比较“坏”的NAT(symmetric)后面的时候才派上用场的。Client也可能在比较有利于P2P通信的网络环境,比如有一个public的IP地址,或是在没那么坏的NAT(non-symmetric)后面, 那么client可以直接建立连接或是通过STUN协议学习到映射地址来进行通信,而不必动用用relay server。有这么几种情况,有人就想了一个办法,由一组比较系统的步骤,将这几种情况都统一考虑进来,又这些步骤可以找到适合具体情况的传输方法,那就是 Interactive Connectivity Establishment (ICE).
基本原理就是:
client本身有一个local的IP,可以作为传输的一个候选地址(candidate);
client通过STUN协议和STUN server交互可以得到它在public 网络上的映射地址(server reflexive), 也作为可能通信的candidate;
再有就是relay server分配的relayed server address,作为另一个candidate.
这些candidate收集起来通过某种信令(比如说SIP,或是XMPP)由server中转发给对方。
双方对这些候选做交互性地check(适用专用的binding request消息)。找到双方的一对地址用来建立P2P传输的连接。
网上看到一个图示不错,贴进来:
(图片来自: http://www.voiptraversal.com/images/offer_response.gif)
Jingle采用了ICE这种做法,只是有点不同,ICE协议里头说client要收集完所有candidate才发给对方,而Jingle里头则不用,提倡有candidate就发,说这样可以加快建立连接的速度。可参考XEP-0176 Jingle ICE-UDP Transport Method。
- 千里