XMPP:Smack客户端无法接收聊天消息。

4
我一直在通过Smack和Openfire服务器进行XMPP聊天的尝试中遇到了很多问题。 我的问题如下:
每当一个用户向另一个用户发送消息时,该消息会被正确地接收到另一个用户。但是任何回复都不会显示在第一条消息的发送者处。 因此,用户1成功地向用户2发送了消息。然后,用户2无法向用户1发送任何回复。 另一方面,如果我重新启动并让用户再次登录,则用户2可以向用户1发送消息,但反之则不行。
我的意思是,只有聊天的发起者才能发送消息,接收者无法回复。
我的代码看起来像这样
    package xmpp;


public class XMPPClient{

private static final int packetReplyTimeout = 500; // millis
private XMPPConnection connection;
private ChatManager chatManager;
private MessageListener messageListener;
private ConnectionConfiguration config;
private MyTimer t = MyTimer.getInstance();
private ArrayList<String> threadPool = new ArrayList<String>();

public XMPPClient()
{
    SmackConfiguration.setPacketReplyTimeout(packetReplyTimeout);

    //define openfire server information

    config = new ConnectionConfiguration("localhost",5222);
    config.setSASLAuthenticationEnabled(false);
    config.setSecurityMode(SecurityMode.disabled);

    connection = new XMPPConnection(config);

    //connect to server
    t.start("Connecting to server...");
    try {
        connection.connect();
    } catch (XMPPException e) {
        System.err.println("Failed to connect to server! Connect to VPN!\t"+e.getMessage());
        System.exit(0);
    }
    t.end("Connection took ");

    //setup chat mechanism
    chatManager = connection.getChatManager();
    chatManager.addChatListener(
            new ChatManagerListener() {
                @Override
                public void chatCreated(Chat chat, boolean createdLocally)
                {
                    if (!createdLocally)
                        chat.addMessageListener(new MyMessageListener());
                }
    });
}
public boolean login(String userName, String password, String resource) {       
    t.start("Logging in...");
    try {
        if (connection!=null && connection.isConnected()) 
            connection.login(userName, password, resource);
        //set available presence
        setStatus(true);
    } 
    catch (XMPPException e) {
        if(e.getMessage().contains("auth")){
            System.err.println("Invalid Login Information!\t"+e.getMessage());
        }
        else{
            e.printStackTrace();
        }
        return false;
    }
    t.end("Logging in took ");
    return true;
}
public void setStatus(boolean available) {
    if(available)
        connection.sendPacket(new Presence(Presence.Type.available));
    else
        connection.sendPacket(new Presence(Presence.Type.unavailable));
}

public void sendMessage(String message, String buddyJID) throws XMPPException {
    System.out.println(String.format("Sending mesage '%1$s' to user %2$s", message, buddyJID));
    boolean chatExists = false;
    Chat c = null;
    for(String tid : threadPool)
    {
        if((c = chatManager.getThreadChat(tid)) != null)
        {
            if(c.getParticipant().equals(buddyJID))
            {
                if(checkAvailability(buddyJID))
                {
                    chatExists = true;
                    break;
                }
                else
                {
                    threadPool.remove(tid);
                    break;
                }
            }
        }
    }
    if (chatExists)
    {
        Chat chat = c;
        chat.sendMessage(message);
    }
    else
    {
        Chat chat = chatManager.createChat(buddyJID, messageListener);
        threadPool.add(chat.getThreadID()); System.out.println(chat.getThreadID());
        chat.sendMessage(message);
    }
}

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

public boolean checkAvailability(String jid)
{
    System.out.print("Checking availability for: "+jid+"=");
    System.out.println(connection.getRoster().getPresence(jid).isAvailable());
    return connection.getRoster().getPresence(jid).isAvailable();
}

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

}

import org.jivesoftware.smack.packet.Message;

public class MyMessageListener implements MessageListener {
@Override
public void processMessage(Chat chat, Message message) {
    String from = message.getFrom();
    String body = message.getBody();
    System.out.println(String.format("Received message '%1$s' from %2$s", body, from));
}

我不确定问题出在哪里,有什么建议吗?可以提供示例代码吗?

谢谢 <3


能否在这里提供相关的代码,以便实际发送和接收(尽可能简洁)。我们并不想阅读整篇博客,并且其中散布着零散的代码片段。 - Robin
3个回答

2

我不确定这是否能帮到你,但是我可以用这段代码得到回复:

public void chat(String AddressedUser) throws NotConnectedException {
    //Create username whom we want to send a message
    String userToSend = AddressedUser + "@" + serverDomain;

    ChatManager chatmanager = ChatManager.getInstanceFor(connection);
    Chat newChat = chatmanager.createChat(userToSend , new MessageListener() {
        @Override
        public void processMessage(Chat chat, Message message   ) {
            // TODO Auto-generated method stub
            System.out.println("Received message: " + message);

        }
    });

    try {
        newChat.sendMessage("Hey");
    }
    catch (XMPPException e) {
        System.out.println("Error Delivering block");
    }

}

我发送“Hey”,然后我会在我的logcat中看到其他用户写的任何内容。

1

您没有指定接收者是什么,例如,如果它是现有客户端(例如Spark),还是更多的自定义代码。这将非常有帮助,同时也需要知道您正在使用哪个版本的Smack。

那段代码有几个问题。

  • 它会为每个发送的消息创建新的Chat对象,而不是简单地重用相同的聊天。
  • 没有注册ChatManagerListener来处理与现有聊天无关的新聊天消息。

@Robin,我在发送xmpp消息时遇到了问题,你能否前往此链接帮助解决问题? - nawaab saab

0

1
你发布的链接中除了后面的帖子之外没有任何有关消息传递的代码。而且即使是那段代码也和我正在使用的一样。 - saada
必须有一些不同之处,因为我已经运行了那段代码并且它完美地运行,既发送又接收。也许是服务器错误。 - Vedant Agarwala
我甚至已经修改了代码,使用Swing组件而不是基本的系统IO,这也很好地工作了。 - Vedant Agarwala
链接已失效,有没有新的链接或示例? - Wasim K. Memon

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