使用 Smack 和 Openfire 发送/接收消息时遇到问题

Posted

技术标签:

【中文标题】使用 Smack 和 Openfire 发送/接收消息时遇到问题【英文标题】:Having trouble sending/receiving messages with Smack and Openfire 【发布时间】:2016-08-03 08:22:15 【问题描述】:

我在使用 Smack 和 Openfire 发送/接收消息时遇到了问题。目前我的设置涉及两台计算机。两台计算机都运行一个启动程序的安卓模拟器。该程序首先启动登录活动,然后启动聊天界面活动。聊天界面目前不做任何事情;一旦 ChatInterface 活动启动,就会自动发送一条消息。

一台计算机(笔记本电脑)充当服务器,台式计算机连接到笔记本电脑服务器(Openfire)。查看笔记本电脑上的 Openfire 用户摘要,两个用户似乎都可用并准备好聊天。但是,当它接收消息时,什么也没有出现。消息不会打印在 ListView 等视图对象上,而是打印在日志上。

以下是笔记本电脑代码:

private static final String TAG = "MSG";

private ListView screen;
private EditText textEditor;
private Button sendButton;    

private final String Host = "10.0.2.2";
private final int port = 5222;

private   AbstractXMPPConnection connection;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat_interface);

    screen = (ListView) findViewById(R.id.ScreenView);
    textEditor = (EditText) findViewById(R.id.TextEditBox);
    sendButton = (Button) findViewById(R.id.SendButton);

    Log.d(TAG, "onCreate Chat Interface");

    final String username = getIntent().getExtras().getString("Username");
    final String password = getIntent().getExtras().getString("Password");

    new AsyncConnect().execute(username, password);

    sendButton.setOnClickListener(new View.OnClickListener()
        public void onClick(View v) 
        
    );

    Log.d(TAG, "Success");



public class AsyncConnect extends AsyncTask<String, Void, Void>

    ProgressDialog pdLoading = new ProgressDialog(ChatInterface.this);

    protected void onPreExecute()
    
        pdLoading.setMessage("Loading...");
        pdLoading.show();
    

    protected Void doInBackground(String...params)
    
        XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
        configBuilder.setUsernameAndPassword(params[0], params[1]);
        configBuilder.setServiceName("Openfire");
        configBuilder.setHost(Host);
        configBuilder.setPort(port);
        configBuilder.build();

        configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled); // Remove this later could be security threat
        connection = new XMPPTCPConnection(configBuilder.build());

        try 

            connection.connect();
            connection.login();
            Log.d(TAG, "Logged on");
            Log.d(TAG, "Connection: " + connection.getUser());


            if(params[0].equals("test2") && params[1].equals("test2!")) 
                Log.d(TAG, "Entered test2");




                ChatManager chatManager = ChatManager.getInstanceFor(connection);
                Log.d(TAG, "ChatManager");

                Chat newChat = chatManager.createChat("LoveJack@yahoo.com", new ChatMessageListener()

                    public void processMessage(Chat chat, Message message)
                    
                        Log.d(TAG, "Received Message From Desktop: " + message.getBody());

                    

                );

                newChat.sendMessage("This is Jane Doe");
                chatManager.addChatListener(
                        new ChatManagerListener() 

                            @Override
                            public void chatCreated(Chat chat, boolean createdLocally) 

                                Log.d(TAG, "Entered chatCreated");

                                if (!createdLocally) 

                                    Log.d(TAG, "Entered Locally");
                                    chat.addMessageListener(new ChatMessageListener() 
                                        @Override
                                        public void processMessage(Chat chat, Message message) 

                                            try 
                                                Log.d(TAG, "Incoming message...");
                                                Log.d(TAG, "Received message from Desktop: " + message.getBody());
                                                Log.d(TAG, "Message Received");

                                             catch (Exception e) 
                                                e.printStackTrace();
                                            


                                        
                                    );

                                
                            
                        );

                Log.d(TAG, "Listened");
            



        
        catch(SmackException.ConnectionException e)
        
            e.printStackTrace();
            Log.d(TAG, "SmackException.ConnectionException");
        
        catch(XMPPException e)
        
            e.printStackTrace();
            Log.d(TAG, "XMPPException");
        
        catch(IOException e)
        
            e.printStackTrace();
            Log.d(TAG, "IOException");
        
        catch(SmackException e)
        
            e.printStackTrace();
            Log.d(TAG, "SmackException");
        
        return null;
    

    protected void onPostExecute(Void params)
    
        pdLoading.dismiss();
    

以下是桌面代码:

private static final String TAG = "MSG";

private ListView screen;
private EditText textEditor;
private Button sendButton;


private final String Host = "192.168.1.152";
private final int port = 5222;

private AbstractXMPPConnection connection;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat_interface);

    screen = (ListView) findViewById(R.id.ScreenView);
    textEditor = (EditText) findViewById(R.id.TextEditBox);
    sendButton = (Button) findViewById(R.id.SendButton);

    Log.d(TAG, "onCreate Chat Interface");

    final String username = getIntent().getExtras().getString("Username");
    final String password = getIntent().getExtras().getString("Password");

    sendButton.setOnClickListener(new View.OnClickListener()
        public void onClick(View v)
        
    );

    new AsyncConnect().execute(username, password);
    Log.d(TAG, "Success");


public class AsyncConnect extends AsyncTask<String, Void, Void> 
    ProgressDialog pdLoading = new ProgressDialog(ChatInterface.this);

    protected void onPreExecute() 
        pdLoading.setMessage("Loading...");
        pdLoading.show();
    

    protected Void doInBackground(String...params) 
        XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
        configBuilder.setUsernameAndPassword(params[0], params[1]);
        configBuilder.setServiceName("Openfire");
        configBuilder.setHost(Host);
        configBuilder.setPort(port);
        configBuilder.build();

        configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled); // Remove this later could be security threat
        connection = new XMPPTCPConnection(configBuilder.build());

        try 

            connection.connect();
            connection.login();
            Log.d(TAG, "Logged on");
            Log.d(TAG, "Connection: " + connection.getUser());
            if(params[0].equals("test1") && params[1].equals("test1!"))
            
                Log.d(TAG, "Entered test1");
                ChatManager chatmanager = ChatManager.getInstanceFor(connection);
                Log.d(TAG, "ChatManager");
                Chat newChat = chatmanager.createChat("HumbleBee001@yahoo.com", new ChatMessageListener() 

                    @Override
                    public void processMessage(Chat chat, Message message) 

                       Log.d(TAG, message.getBody());
                    
                );

                newChat.sendMessage("This is John Doe");
                Log.d(TAG, newChat.getParticipant());
                Log.d(TAG, "Message sent");
            

        
        catch(SmackException.ConnectionException e)
        
            e.printStackTrace();
            Log.d(TAG, "SmackException.ConnectionException");
        
        catch(XMPPException e)
        
            e.printStackTrace();
            Log.d(TAG, "XMPPException");
        
        catch(IOException e)
        
            e.printStackTrace();
            Log.d(TAG, "IOException");
        
        catch(SmackException e)
        
            e.printStackTrace();
            Log.d(TAG, "SmackException");
        
        return null;
    

    protected void onPostExecute(Void params)
    
        pdLoading.dismiss();
    

没有调用 processMessages 方法,因为 logcat 中没有打印任何内容。

我不太确定问题出在哪里。一些 Smack 文档似乎已经过时了,并且没有很多很好的 API 资源。有人知道可能是什么问题吗?

【问题讨论】:

【参考方案1】:

我看到很多问题,我建议更好地阅读文档。

我发现了什么:

XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
        configBuilder.setUsernameAndPassword(params[0], params[1]);
        configBuilder.setServiceName("Openfire");
        configBuilder.setHost(Host);
        configBuilder.setPort(port);
        configBuilder.build();

ServiceName 这是您的服务器的名称,默认情况下是安装 Openfire 的机器名称。如果您没有特定配置来分配此名称,您将遇到麻烦。在管理控制面板上检查正确的名称(Openfire 日志会说明它在哪里听...类似于yourmachinename:9090

最好将连接功能与登录功能分开。 我建议删除 setUsernameAndPassword 并在connection.login() 调用中使用params[0]params[1]。 您错过了 Resource(它是一个字符串,例如 "Spark"、"Smack"、"android"、" MyXmppClient"),如果你错过了,还有一些默认配置和问题。

所以我建议改变一下,例如:

connection.login(param[0],param[1],"MyAndroidApp");

用户名必须小写,Openfire 在他的代码中有一些防御性的 toLowerCase() 但最好避免使用大写字母。 所以一定要使用小写的JID。

LoveJack@yahoo.com 必须是:lovejack@yahoo.com

但是,这与电子邮件无关:您需要一个 JID,所以它不是“yahoo.com”,而是 @yourservername(与我谈到的 ServiceName 相同的问题)之前)。

你正试图在名为“yahoo.com”的 XmppServer 上与“LoveJack”创建一个聊天,我认为这不是你的目标。

可能您没有正确注册您在服务器上使用的用户,请尝试检查(如果在 Yahoo 上谈论这就是您想要的,也许您必须阅读一些东西 like this)

【讨论】:

哇,谢谢你清理了很多东西。资源的意义何在?它应该是某种标识符吗? 它是客户端的标识符(让我说像“Skype”),但如果您不设置它,则有一个默认值;将 meggages 传送到正确的设备所需的资源(用例:您同时连接了智能手机和平板电脑),但默认值可能会误导 xmpp 服务器。如果这有帮助,请不要忘记接受答案;)

以上是关于使用 Smack 和 Openfire 发送/接收消息时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Smack Api for Android 发送和接收消息

使用 smack API 发送和接收消息

android端怎么接收openfire服务器发送过来的消息

如何在消息 asmack/smack 中添加其他数据?

是否可以使用 Smack API 在 Openfire Server 上监听/监视用户向另一个用户发送的消息?

使用 Smack API (xmpp) 从 Java 回调 JavaFX