Android / XMPP:连接类型更改后无法重新连接到服务器

时间:2011-06-29 17:00:02

标签: android xmpp smack

我目前正在我的大学开发一个项目,这是一个Android-App,它应该向服务器提供数据。

为了做到这一点,我需要通过XMPP与服务器建立或多或少的一致性连接。连接在100%的时间内并不是很重要,但是因为系统应该或多或少地对用户不可见,所以用户交互应该是最小的。

服务器和客户端都是xmpp-clients。我使用jabber.org作为xmpp服务器。

我有一个Android服务,它建立与服务器的连接并提供数据,这很好。

现在我尝试在连接丢失或从Wifi更改为GSM时重新连接服务。我想尝试使用收听NETWORK_STATE_CHANGED_ACTION的广播接收器来完成这项工作。但我甚至没有这么做。

这就是问题:我尝试运行应用程序然后只是禁用我的wifi。我的电话比自动切换到GSM,我失去了我的连接(我预期)。但是当我尝试手动重新连接(例如重新启动服务)时,我从服务器收到错误。我的状态仍然“可用”。从那一刻起,它需要太长时间,直到我再次连接。

06-29 18:12:14.888: WARN/System.err(14246): resource-constraint(500)
06-29 18:12:14.890: WARN/System.err(14246):     at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:110)
06-29 18:12:14.890: WARN/System.err(14246):     at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:404)
06-29 18:12:14.890: WARN/System.err(14246):     at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
....

我实际连接到xmpp服务器,但它没有传递我的消息:

06-29 18:12:14.882: INFO/System.out(14246): 06:12:14 nachm. RCV  (1079704816): <iq type='error' id='7rhk4-70'><error code='500' type='wait'><resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>

有时我没有收到错误,但仍然没有传递消息。

所以我认为服务器不允许我连接,因为在尝试重新连接之前我没有断开连接。我发现这很奇怪,因为我认为你甚至可以从多个客户端连接到一个帐户。

我发布了一些我认为可能相关的代码:

public void connectToServer() throws XMPPException {

    ConnectionConfiguration config = new ConnectionConfiguration(
            serverADD, port,
            service);

    connection = new XMPPConnection(config);
    connection.connect();

    SASLAuthentication.supportSASLMechanism("PLAIN", 0);

    connection.login(user_JID,password);

    Presence presence = new Presence(Presence.Type.available);
            presence.setStatus("available");
            presence.setPriority(24);
    presence.setMode(Presence.Mode.available);
        connection.sendPacket(presence);
}

这是我发送消息的方式:

public void sendMessage(String message, String recipient) throws XMPPException {

    chat = connection.getChatManager().createChat(recipient, this);
    chat.sendMessage(message);

}

有谁有想法如何解决这个问题?只要我的消息传递到服务器,我甚至会使用“脏”技巧。

顺便说一下:发件人和收件人的jids总是一样的(初始设置后)。万一有人认为这可能很重要。

1 个答案:

答案 0 :(得分:5)

Smack断开连接时的死锁

正如Airsource有限公司在评论中提到的那样:Smack在disconnect()中遇到了僵局,其中SMACK-278已陷入僵局。我有ade a commit that fixes this in my smack fork

Android重新连接处理

对于网络失败者,请查看GTalkSMS receiver。它将发出ACTION_NETWORK_CHANGED意图,布尔额外的“可用”和“失败转移”。当“available = false”和“fallover = false”时,您的服务应该“停止”连接。你如何“停止”连接取决于你。有时即使对SMACK-278的修复,disconnect()也需要很长时间,这就是为什么我们执行disconnect in an thread that will abort after x seconds然后创建一个新的Connection实例。当收到“available = true”的意图时,我们重新连接。

您将在GTalkSMS源代码中找到其他示例。我让应用程序永久运行,它实现了稳定但不是100%可用的连接(因为WLAN&lt; - &gt; GSM交换机)。