XMMP服务器使用NAT提供给客户端的公共端点(IP +端口)向NAT后面的客户端发送推送通知。但是,通过NAT将此端点分配给此特定客户端的时间有多长,如果NAT将相同端点分配给另一个客户端,会发生什么?这个问题怎么解决?
答案 0 :(得分:1)
XMPP使用标准TCP连接。只要连接存在,NAT就会保持关联(除非它们被严重破坏)。
更新:我的陈述的最后一部分可能已经扩展了一点。存在可怕的NAT实现 do 。通常这些只是一小部分,但许多(大多数?)流行的XMPP客户端确实会通过空闲连接发送某种keepalive。
您可以使用三种keepalive我会按照带宽/处理要求在此列出:
TCP keepalive是一个很好的轻量级选项,特别是一旦启用它们,它们将由操作系统自动处理。如何启用它们取决于您的语言和框架,但在最低级别,您需要在套接字上启用SO_KEEPALIVE
选项。
TCP keepalive存在两个问题。一个是您无法从应用程序中控制它们(除非您编写特定于平台的代码)。第二个问题是某些NAT实现被所以打破,他们也会忽略TCP keepalive!但是你现在希望降到很小的比例。
另一个选择是whitespace keepalives。由于这些涉及跨流的数据,因此即使是忽略了Keepalive的破坏的NAT也应该是安全的。
空白Keepalive只是涉及在空闲时随时在XMPP流中发送空格字符('')。 XML和XMPP允许元素之间有无限的空格,收件人只会忽略它。
最后,您可以使用完全成熟的XMPP pings (XEP-0199)。这些涉及到服务器结束实际的<iq/>
'get'节,然后必须回复。这可以确保数据在两个方向上流动,并且即使是最破坏的NAT实现也可以使您的连接保持活动状态。
好的,我应该提到一个更糟糕的NAT类。我已经看到NAT会因为一系列原因而简单地“忘记”你的映射,包括它们的映射表已经满了,或者只是在一个定时器之后。您无法解决这些问题,它们不适用于任何长期存在的TCP连接。你可能在那时做的最好的事情是使用BOSH(基本上是XMPP over HTTP)。
结论:如果您担心您的应用程序可能会在某些设备后面运行,我建议使用以下算法(确切的时间可能会被调整,但我建议这些作为最小值):
由于破坏NAT设备的行为超出了任何标准协议规范,因此自然不可能设计出一直适用于所有这些设备的完美解决方案。你只需要接受这些只是少数,这对于工作NAT设备都不重要(尽管还有其他类型的网络破坏可能会使常规Keepalive / ping成为一个好主意,具体取决于你的应用程序的需求)。
答案 1 :(得分:0)
解决方案是发送保持活动消息以维护NAT条目。通常使用XMPP空格。例如,每隔十分钟发送一次,以保持对客户的可达性。
您必须记住,NAT不是标准化技术。因此,存在不同的实现。上述评论中提供的RFC来自BEHAVE工作组。