Session XMPP会在NAT环境中工作吗?

Session XMPP会在NAT环境中工作吗?,session,xmpp,protocols,nat,endpoint,Session,Xmpp,Protocols,Nat,Endpoint,XMMP服务器使用NAT向客户机提供的公共端点(IP+端口)向NAT后面的客户机发送推送通知。但NAT将该端点分配给该特定客户机的时间有多长,如果NAT将同一端点分配给另一个客户机会发生什么?如何解决这个问题?XMPP使用标准TCP连接。只要连接还活着,NAT就会保持关联(除非它们被严重破坏) 更新:我声明的最后一部分本可以扩展一点。确实存在严重破坏的NAT实现。一般来说,这只是一小部分,但许多(大多数?)流行的XMPP客户端确实确保它们通过空闲连接发送某种keepalive 您可以使用三种ke

XMMP服务器使用NAT向客户机提供的公共端点(IP+端口)向NAT后面的客户机发送推送通知。但NAT将该端点分配给该特定客户机的时间有多长,如果NAT将同一端点分配给另一个客户机会发生什么?如何解决这个问题?

XMPP使用标准TCP连接。只要连接还活着,NAT就会保持关联(除非它们被严重破坏)

更新:我声明的最后一部分本可以扩展一点。确实存在严重破坏的NAT实现。一般来说,这只是一小部分,但许多(大多数?)流行的XMPP客户端确实确保它们通过空闲连接发送某种keepalive

您可以使用三种keepalive,我将按带宽/处理要求在此处列出它们:

TCP keepalives是一个很好的轻量级选项,特别是一旦启用,它们就会由操作系统自动处理。如何启用它们将取决于您的语言和框架,但在最低级别,您需要在套接字上启用
SO_KEEPALIVE
选项

TCP keepalives有两个问题。一个是您无法从应用程序中控制它们(除非您编写特定于平台的代码)。第二个问题是,一些NAT实现被破坏得太厉害,以至于它们也会忽略TCP keepalives!但你希望现在降到一个很小的百分比

因此,另一个选择是。因为这些涉及数据流的传输,所以即使是忽略keepalives的损坏NAT,您也应该不会受到影响

空格keepalives只涉及在XMPP流空闲时发送空格字符(“”)。XML和XMPP允许元素之间不受限制的空白,接收者只需忽略它

最后,您可以使用完全成熟的。这涉及到向服务器结束一个实际的“get”节,然后服务器必须回复。这确保了数据在两个方向上流动,并且应该使即使是最坏的NAT实现也能保持您的连接

好的,我应该提到的是,还有一种更糟糕的NAT。我见过NAT会因为一系列原因而“忘记”您的映射,包括它们的映射表已满,或者只是在一个计时器之后。您无法解决这些问题,它们不适用于任何长寿命TCP连接。在这一点上,您可能能做的最好的事情就是使用(基本上是通过HTTP的XMPP)

结论:如果您担心您的应用程序可能会在这些设备后面运行,我建议使用以下算法(精确时间可能会有所调整,但我建议将其作为最小值):

  • 如果60秒内未发送任何数据,请发送单个空格字符
  • 如果您已经120秒没有收到任何数据,请向服务器发送XMPP ping
  • 如果服务器没有在合理的时间内回复ping,请重新连接

由于损坏的NAT设备的行为超出了任何标准协议规范,因此自然不可能设计出一个完美的解决方案,使其始终适用于所有NAT设备。您只需接受这是一小部分,而这些都与NAT设备的工作无关(尽管还有其他类型的网络中断,根据应用程序的需要,定期保留/ping可能是一个好主意)。

解决方案是发送保持活动的消息来维护NAT条目。通常使用XMPP空格。每十分钟发送一次,以保持客户端的可达性


你必须记住NAT不是标准化的技术。因此有不同的实现。上述评论中提供的RFC来自BEHAVE工作组

这是错误的。NAT会在一段空闲时间后删除映射项。通常在15到45分钟后。@tobias有些人会的,是的。正如我所说,它们坏得可怕。如果您认为此声明不正确,请说出表示不正确的RFC。然后你可以否决我的答案:)@tobias:我更新了我的答案,更详细地介绍了不同程度的破碎,以及如何解决这些问题。也许还可以提到XEP-0198。一些NAT会在一段时间后终止您的连接,能够快速重新连接并知道您错过了什么是很好的。现在您的答案更完整了。但这样做的原因并不是因为NAT坏了。有些RFC表示在空闲时间后会删除TCP/UDP映射状态。RFC4787建议在5分钟后删除UDP。RFC5382建议在2小时4分钟后删除TCP映射项,而不是使用XMPP空格。应该使用XMPP pings(XEP-0199)。我对此非常不确定。我认为ping/pong用于死点检测。XMPP ping可以起到与空白相同的作用:保持TCP连接处于活动状态,从而防止NAT超时。我们在(a)Smack.Yes中这样做,如果DPD间隔在要求的保持活动间隔范围内。我找不到来源,但我在邮件列表中写道,空格的目标是keepalive,ping的目标是DPD。但你是对的,XMPP ping解决了这两个问题!