0

我正在使用 Smack 3.1.0 和 Java 创建一个即时消息客户端。我遇到的问题与向特定域上的用户发送消息有关。

例如,我有两个用户,1@gmail.com 和 2@gmail.com。1@gmail.com 通过我的 IM 客户端登录到 XMPP。2@gmail.com 通过 gmail.com 和第二次通过 pidgin 登录到 GChat。所以现在我有一个 1@gmail.com 实例和 2 个 2@gmail.com 实例。

gmail 的工作方式,如果 1@gmail.com 向 2@gmail.com 发送消息,则 gmail 和 pidgin 客户端都会收到初始消息。但是如果 gmail 实例响应消息,那么从那时起的每条消息都只会在 1@gmail.com 和 2@gmail.com 的 gmail 实例之间传递。

我想用我的 IM 客户端模仿这种行为。我认为这样做的方法是设置聊天,将初始即时消息发送给收件人的所有实例。然后我会设置一个 MessageListener 来监听响应。当我收到回复时,我必须创建一个新的聊天,指定 2@gmail.com/resource。但后来我不得不写两次 MessageListener。有任何想法吗?这是我正在使用的一些示例代码(该方法AddText()只是将消息附加到我的对话窗格):

recipient = buddy;
setTitle("Instant Message - "+recipient);
chat = com.andreaslekas.pim.PIM.connection.getChatManager().createChat(recipient.getUser(), new MessageListener() {
    public void processMessage(Chat chat, Message msg) {
        //if(chat.getParticipant().indexOf('/')!=-1)
        addText(msg.getBody(), chat.getParticipant(), true);
    }
});

更新 我想用我用来完成这项工作的实际代码来补充下面的答案:

chat = com.andreaslekas.pim.PIM.connection.getChatManager().createChat(recipient.getUser(), new MessageListener() {
    public void processMessage(Chat new_chat, Message msg) {
        if(msg.getFrom().replaceFirst("/.*", "").equals(recipient.getUser()))
        {
            if(buddy_resource==null || !msg.getFrom().replaceFirst(".*?/", "").equals(buddy_resource.getResource()))
            {
                buddy_resource = recipient.getResource(msg.getFrom().replaceFirst(".*?/", ""));
                chat = null;
                chat = com.andreaslekas.pim.PIM.connection.getChatManager().createChat(recipient.getUser()+"/"+buddy_resource.getResource(), new MessageListener(){
                    public void processMessage(Chat new_chat2, Message msg) {
                        addText(msg.getBody(), new_chat2.getParticipant(), true);
                    }
                });
            }
            addText(msg.getBody(), chat.getParticipant(), true);
        }
    }
});

总而言之,我将第一条消息发送到收件人地址的所有资源并等待响应。当我得到响应时,我将当前Chat对象替换为一个新对象,该对象指定响应初始消息的单个资源。代码有点混乱,有两个不同的MessageListener对象可能会组合成一个新类。但它有效。

4

2 回答 2

2

到目前为止,我了解 Message Carbon (XEP - 0280) 将解决您的问题。如果您启用碳,它会将消息分发到用户的所有记录资源。在您的情况下,如果 1@gmail.com 向 2@gmail.com 发送消息,它将被分发到 2@gmail.com 的所有记录资源。这是一个使用 smack 的代码示例,

CarbonManager cm = CarbonManager.getInstanceFor(connection);
cm.enableCarbons();
cm.sendCarbonsEnabled();

首先确保您的服务器支持 Message Carbon。然后像往常一样发送消息。

于 2016-09-05T18:29:11.037 回答
0

在您的 MessageListener 中,为什么不总是回复发件人?我认为您可以通过调用 msg.getSender() 或 getFrom() 之类的方法来获取它(我现在在移动设备上,无法查看)

于 2011-01-22T02:09:47.793 回答