繁体   English   中英

无法使用Smack(Java)接收消息?

[英]Unable to receive Message using Smack (Java)?

我正在尝试建立一个简单的示例,以使用Openfire使用Smack API发送和接收消息。 我已经按照本教程

有人在这里问过同样的问题,但是答案提到了我已经用于接收聊天的代码。 这些示例中的许多示例也使用相同的方法。

public class Receiver {

    public static void main(String a[]) throws XMPPException, InterruptedException {
        XMPPConnection connection = new XMPPConnection("192.168.1.38");
        System.out.println(connection);
        connection.connect();


        connection.login("test2", "123456");
        EFLogger.LogInfo("Receiver", "Connected [ " + connection.isConnected() + " ]");

        connection.getChatManager().addChatListener(new ChatManagerListener() {
            public void chatCreated(Chat chat, boolean b) {
                System.out.println("In Message Listener ! ");
                chat.addMessageListener(new MessageListener() {
                    public void processMessage(Chat chat, Message message) {
                        System.out.println("Message [ " + message.toXML());
                    }
                });
                try {
                    chat.sendMessage("Hello");
                } catch (XMPPException e) {
                    e.printStackTrace();
                }
            }
        });


        while (true) {

        }
    }
} 

为了发送,我正在使用

public class Main {

    public static void main(String[] args) throws Exception {

        String username = "test";
        String password = "123456";

        XmppManager xmppManager = new XmppManager("192.168.1.38", 5222);

        xmppManager.init();
        xmppManager.performLogin(username, password);
        xmppManager.setStatus(true, "Hello everyone");

        //As @MrPk suggested I shouldn't use "/Smack"
        //String buddyJID = "test2@ef-app2/Smack";

        String buddyJID = "test2@ef-app2";
        String buddyName = "test";
        xmppManager.createEntry(buddyJID, buddyName);


        for (int i = 0; i < 10; i++) {
            xmppManager.sendMessage("Hello mate from test " + i, "test2");
        }

        boolean isRunning = true;

        while (isRunning) {
            Thread.sleep(50);
        }

        xmppManager.destroy();

    }
} 

此类是XMPPManager

/**
   This class is responsible for handling all Actions related to Chat    Management. Connection, Login, Status, Create Entry and Message Listener.
*/
public class XmppManager {

    private static final int packetReplyTimeout = 500; // millis

    private String server;
    private int port;

    private ConnectionConfiguration config;
    private XMPPConnection connection;

    private ChatManager chatManager;
    private MessageListener messageListener;


    public XmppManager(String server, int port) {
        this.server = server;
        this.port = port;
    }

    public void init() throws XMPPException {

        EFLogger.LogInfo("XmppManager", String.format("Initializing connection to server %1$s port %2$d", server, port));

        SmackConfiguration.setPacketReplyTimeout(packetReplyTimeout);
//        SmackConfiguration.DEBUG = true;
        config = new ConnectionConfiguration(server, port);
        config.isDebuggerEnabled();

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

        EFLogger.LogInfo("XmppManager", "Connected: " + connection.isConnected());

        chatManager = connection.getChatManager();
        //messageListener = new MyMessageListener();

    }

    public void performLogin(String username, String password) throws XMPPException {
        if (connection != null && connection.isConnected()) {
            EFLogger.LogInfo("XmppManager", "Before login userName [ " + username + " ] password [ " + password + " ]");
            connection.login(username, password);
            System.out.printf("Logged in ");

        }
    }

    public void setStatus(boolean available, String status) {

        Presence.Type type = available ? Type.available : Type.unavailable;
        Presence presence = new Presence(type);

        presence.setStatus(status);
        connection.sendPacket(presence);

    }

    public void destroy() {
        if (connection != null && connection.isConnected()) {
            connection.disconnect();
        }
    }

    public void sendMessage(String message, String buddyJID) throws XMPPException {
        EFLogger.LogInfo("XmppManager", String.format("Sending mesage '%1$s' to user %2$s", message, buddyJID));
        Chat chat = chatManager.createChat(buddyJID, messageListener);
        chat.sendMessage(message);
    }

    public void createEntry(String user, String name) throws Exception {
        EFLogger.LogInfo("XmppManager", String.format("Creating entry for buddy '%1$s' with name %2$s", user, name));
        Roster roster = connection.getRoster();
        roster.createEntry(user, name, null);
    }

    static class MyMessageListener implements MessageListener {

        public void processMessage(Chat chat, Message message) {
            String from = message.getFrom();
            String body = message.getBody();
            EFLogger.LogInfo("XmppManager", String.format("Received message '%1$s' from %2$s", message.getError(), from));
        }

    }

}

首先,我认为buddyID一定有问题,我有这两个用户testtest2而XMPPdomain是ef-app2所以我将buddyJID test2@ef-app2/Smack smack设置为默认资源。

编辑

建议@MrPk不应该使用/ Smack ,但是不要碰运气。

但仍然没有影响,我仍然无法收到任何消息。 我不确定我缺少什么。 如果您有兴趣重现同样的问题,你可以找到IntelliJ IDEA的项目在这里你可以得到有关该问题的一些细节在这里

救命!

启动聊天应用程序时,我使用了相同的教程。 它或多或少是一个很好的教程,但实际上是极简主义:让我们逐点检查主要改进和错误修复。

在开始之前,您将需要2个用户:您可以从test2@ef-app2消息发送给自己(您只能使用Broadcast进行广播,但这太高级了)。 只需在服务器上注册第二个用户即可。

因此,您将需要test1@ef-app2 (与之聊天)和test2@ef-app2 (在您的应用中登录)。

首先,建议您在计算机上安装Spark客户端。 因此,您将能够拥有一个“肯定能正常工作”的客户端,并且您将能够在Spark和Java应用程序之间实时进行聊天,当然需要使用2个用户。 我喜欢Spark,因为它具有出色的调试器,可让您检查发送和接收的Stanzas,因此基本上,当您不知道自己是否正确时,只需检查Spark的功能即可。

XmppManager

SmackConfiguration.setPacketReplyTimeout(3000); //default

不要减少默认超时。 我从50000开始,现在有7000(表示7秒)。

在此之前或之后,您需要改进连接的配置,或多或少像这样:

protected XMPPTCPConnectionConfiguration config;
protected AbstractXMPPConnection connection;

this.config = XMPPTCPConnectionConfiguration.builder()
                .setServiceName(serviceName)  //Often is NOT the IP address of Host
                .setHost(server)
                .setPort(port)
                .setSecurityMode(SecurityMode.disabled) //if you don't need
                .setDebuggerEnabled(true)  //really helpfull
                .build();


this.connection = new XMPPTCPConnection(config);
this.connection.connect();

在不提供用户,密码和资源的情况下连接服务器。

注意: config.isDebuggerEnabled(); 这是一个获取,而不是集合(因此,您不启用它,而只是che之以鼻...)

要登录,我建议像这样设置一个自定义 Resource标识符 (有些东西没有使用或默认设置就会损坏 )->避免使用“ Smack”和“ Spark”进行更好的调试。 使用类似“ MyApp”的名称。

connection.login(username, password, "MyApp");  

ChatManagerListener-ChatMessageListener

基本思想是:每当您在“我”和“另一个人”之间开始聊天时,客户端应用程序都必须为“另一个人”的传入消息添加一个侦听器。 因此,您必须向ChatManager添加一个用于管理单个聊天侦听器的侦听器。 我将向您展示“基本所有匿名”版本,如果愿意,您可以拆分为单个定义的类。

//add to ChatManager a listener to manage incoming "person"
        ChatManager.getInstanceFor(connection).addChatListener(
                new ChatManagerListener() {
                    @Override
                    public void chatCreated(Chat chat, boolean createdLocally)
                    {
//if it's the first message in session between 2 users
                        if (!createdLocally)
                        {
//add a listeners for those message just once
                            chat.addMessageListener(new ChatMessageListener()
                            {

                                @Override
                                public void processMessage( Chat arg0, Message arg1 )
                                {
//example to read something in standard output
                                    String from = message.getFrom();
            String body = message.getBody();

            if (body != null)
            {
                System.out.println(String.format("============ Received message '%1$s' from %2$s\n============", body, from));
            }
            else
            {
                System.out.println("SYSTEM: ping (body null)");
            }
                                }
                            };
                        }
                    }
                }); 

主(聊天应用程序)

基本上,您必须再等待一点时间才能销毁客户端。 如果您之前使用独立的客户端(例如Spark I)将用户“ test2”连接到服务器“ ef-app2”,则将轻松检查是否收到任何消息。 主要外观如下:

xmppManager.performLogin("test2@ef-app2", "123456". "MyApp");
xmppManager.createEntry("test1@ef-app2", "My friend"); //test1 ONE! 

xmppManager.sendMessage("Hello world", "test1@ef-app2");


    boolean isRunning = true;

    while (isRunning) {
        Thread.sleep(50000);
        i++;

        if (i > 2)
        {
            //xmppManager.performLogout();
            isRunning = false; 
             xmppManager.destroy();
        }
    }

最后

检入调试发生了什么以及发送和接收的最终XML是什么。 您将可以与Spark one进行比较。 如果默认消息不起作用,请尝试以下代码:

Message message = new Message();
        message.setBody(body);
        message.setType(Message.Type.chat);
        message.setTo("test2@ef-app2");
        message.setFrom("test1@ef-app2");
        try {
            connection.sendStanza(message);
        } catch (NotConnectedException e) {
            System.out.println("Not connected!");
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM