Smack客户端-尽管连接中断,用户仍然处于“在线”状态

11

我在使用Smack构建一个小型XMPP客户端/机器人时遇到了一种相当奇怪的行为。我设置了连接以及ConnectionListener和ChatManagerListener。这很好地工作,我可以与运行在便携设备上的应用程序聊天。

为了测试失去连接的情况,我拔下了便携设备的以太网电缆。我期望XMPP客户端失去连接,并且用户将被设置为“离线”在用户好友的名单中。然而实际发生的是,该用户仍显示为“在线”,我的客户端的ConnectionListener既没有触发connectionClosed也没有reconnectionFailed或其他任何事件。

当我重新插入以太网电缆时,有时就像连接一直存在一样。离线消息会得到处理,我可以像以前一样聊天。

其他时候,我的客户端完全无法访问和运作,似乎所有的监听器都消失了...但没有抛出任何异常。

这是一种相当奇怪且无法控制的行为,对我来说将使整个客户端无法使用,因为我无法确定客户端在连接中断后是否能正常运行。

是否有其他人遇到过这样的问题或者有任何提示是(不)发生了什么?

如果需要,我可以提供我的代码,但它实际上只是从Smack文档中复制并粘贴的。

2个回答

8
您实际上描述了两种不同的效果。让我们从标题中提到的那个开始:即使连接突然断开并且未经清理,服务器仍然假定用户在线,并显示其在线状态。原因很简单,即服务器尚未注意到客户端的断开连接,因为XMPP数据流没有进行干净的终止。大多数XMPP服务器每隔X分钟通过ping检查客户端。如果客户端未响应,则被认为已断开连接并显示为离线状态(如果它是该JID的最后一个连接资源)。这在此处并未发生,这种情况并不罕见。因为有时您需要长时间的超时(半个小时或更长)。
同样适用于另一侧。如果使用PingManager或PingManagerWithAlarmManager(针对Android),Smack也会每隔X分钟发送XMPP ping。如果所使用的套接字存在任何问题,则会抛出异常。
我希望我能指导您正确的方向。您必须自己调试,以了解为什么在您的情况下连接没有以异常方式终止。
最后一件事:即使以太网电缆插入和拔出,TCP连接也可以轻松存活一些超时。涉及到OSI模型的各个层面上的许多超时:NAT、TCP、XMPP等。

谢谢您的澄清,它们可能会对我有所帮助。也许我会更有耐心,在重新插入电缆之前等待超过1-2分钟。无论如何,听众有时保持调谐,有时不保持调谐的问题仍然是一些神秘的。但我想我会为此开一个新的问题。 - signpainter
2
我想补充一下,TCP 的这种行为不是一个 bug,而是一个很棒的功能,但很少有人能够欣赏到它。不需要重新连接和进行相当昂贵的 XMPP 流设置可以节省大量的往返时间。你可能想要的是让操作系统告诉你连接丢失和恢复,以便您可以检查连接是否还存在。如果是的话,就像没有发生过任何事情一样继续运行,否则重新连接。XEP-0198 重新连接也很棒。 - Zash

0

你必须显式地使用disconnect()方法来终止连接,否则服务器将不得不定期ping你并意识到你已经离线了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接