我正在使用 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
对象可能会组合成一个新类。但它有效。