Android - XMPP:“已经登录到服务器”异常

Posted

技术标签:

【中文标题】Android - XMPP:“已经登录到服务器”异常【英文标题】:Android - XMPP : 'Already logged in to server' exception 【发布时间】:2015-04-12 05:14:25 【问题描述】:

我正在为我的聊天应用程序使用 aSmack 和 Openfire。

我编写了后台服务,它监听互联网连接并连接到 XMPP 服务器。

当服务尝试连接 XMPP 服务器时,它会抛出“已经登录到服务器”异常。

我在服务器设置中将资源策略设置为“总是被踢”,并尝试在 login() 方法中将“null”作为第三个参数传递,但它们都不适合我。谁能帮帮我?

04-11 18:09:50.293: E/androidRuntime(25422): FATAL EXCEPTION: Thread-2212
04-11 18:09:50.293: E/AndroidRuntime(25422): Process: com.example.singlechat:remote, PID: 25422
04-11 18:09:50.293: E/AndroidRuntime(25422): java.lang.IllegalStateException: Already logged in to server.
04-11 18:09:50.293: E/AndroidRuntime(25422):    at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:232)
04-11 18:09:50.293: E/AndroidRuntime(25422):    at org.jivesoftware.smack.Connection.login(Connection.java:371)
04-11 18:09:50.293: E/AndroidRuntime(25422):    at com.example.singlechat.BackgroundService$3.run(BackgroundService.java:173)
04-11 18:09:50.293: E/AndroidRuntime(25422):    at java.lang.Thread.run(Thread.java:818)

连接代码:

// Connect XMPP Server
public void connectXMPPServer() 

    Thread t = new Thread(new Runnable() 

        @Override
        public void run() 

            // Create a connection
            ConnectionConfiguration connConfig = new ConnectionConfiguration(
                    HOST, PORT, SERVICE);
            connConfig.setReconnectionAllowed(true);

            xmppConnection = new XMPPConnection(connConfig);

            try 

                xmppConnection.connect();
                Log.i("XMPPChatDemoActivity", "Connected to "
                        + xmppConnection.getHost());
             catch (XMPPException ex) 

                Log.e("XMPPChatDemoActivity", "Failed to connect to "
                        + xmppConnection.getHost());
                Log.e("XMPPChatDemoActivity", ex.toString());
            

            try 

                if (xmppConnection.isConnected()) 

                    xmppConnection.login(USERNAME, PASSWORD);
                    Log.i("XMPPChatDemoActivity", "Logged in as "
                            + xmppConnection.getUser());

                    Presence presence = new Presence(
                            Presence.Type.available);
                    xmppConnection.sendPacket(presence);
                
             catch (XMPPException ex) 

                Log.e("XMPPChatDemoActivity", "Failed to log in as "
                        + USERNAME);
                Log.e("XMPPChatDemoActivity", ex.toString());
            
        
    );
    t.start();


// Broadcast receiver; listens to network state
public BroadcastReceiver networkStateReceiver = new BroadcastReceiver() 

    @Override
    public void onReceive(Context context, Intent intent) 

        try 

            if (isNetworkOn()) 

                Log.i("BackgroundService-BroadcastReceiver",
                        "Network is on");
                connectXMPPServer();
             else if (!isNetworkOn()) 

                Log.i("BackgroundService-BroadcastReceiver",
                        "Network is off");
                xmppConnection.disconnect();
            
         catch (Exception e) 

            Log.e("BackgroundService-networkStateReceiver", e.toString());
        
    
;

// Returns network state
public boolean isNetworkOn() 

    ConnectivityManager connMngr = (ConnectivityManager) getApplicationContext()
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = connMngr.getActiveNetworkInfo();
    return (netInfo != null && netInfo.isConnected());

【问题讨论】:

这个问题你解决了吗? @EagleEye 抱歉。我仍然坚持这一点。 您使用哪个版本的 Smack?我建议更新到最新发布的 Smack 版本(在撰写本文时为 4.1.5)。 @Flow 现在是 19-0.8.10 【参考方案1】:

Openfire 提供了很多自定义选项,例如 Kick resources after logged out 等。但没有一个对我有用。所以try-catch 是剩下的选择。如果有人做了更好的研究,他们的建议将不胜感激。

try 

    xmppConnection.login(USERNAME, PASSWORD);
 catch (IllegalStateException e) 

    Log.e("MessagingService", "Already Logged in as " + xmppConnection.getUser());

Log.i("MessagingService", "Logged in as " + xmppConnection.getUser());

【讨论】:

【参考方案2】:

这是 Smack 库的问题 - XMPP Presence 节总是在启用扩展时发送,无论设置如何。

查看开发者帖子:https://community.igniterealtime.org/thread/55778

您可以通过从 app/build.gradle 中删除 Smack 扩展依赖项来验证这一点。如果您不再有异常,则意味着 Smack 开发人员应该提供解决方案。

【讨论】:

以上是关于Android - XMPP:“已经登录到服务器”异常的主要内容,如果未能解决你的问题,请参考以下文章

XMPP 与 Android 交互

Android基于xmpp的即时通讯应用

如何创建nodejs xmpp服务器和android xmpp客户端

如何在Android中创建使Xmpp与XMPP服务器保持连接的服务?

android中的XMPP连接错误

用于 React Native Android 的 XMPP 库