在初始广播消息后向特定 Smack 域发送消息
Posted
技术标签:
【中文标题】在初始广播消息后向特定 Smack 域发送消息【英文标题】:Sending messages to specific Smack domains after initial broadcast message 【发布时间】:2011-01-22 01:54:17 【问题描述】:我正在使用 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@gmail.com 的 2 个实例。
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
对象,它们可能会组合成一个新类。但它有效。
【问题讨论】:
【参考方案1】:到目前为止,我了解 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。 然后像往常一样发送消息。
【讨论】:
【参考方案2】:在您的 MessageListener 中为什么不总是响应发送者?我认为您可以通过调用 msg.getSender() 或 getFrom() 之类的方法来获取它(我现在在移动设备上,无法查看)
【讨论】:
msg.getFrom() 是一个字符串。回复发件人需要 Chat newChat = connection.getChatManager().createChat(msg.getFrom(), new MessageListener()); 你能把那个MessageListener设置为null吗?因为你已经有一个监听器来接收响应消息。 好吧,我可以将该侦听器设置为 null,但我会创建一个新的 Chat 实例,因此不会处理任何传入消息,因为旧侦听器已被破坏。 如果它被破坏了,有一个新的监听器有什么问题?那么如果 pidgin 客户端在 gtalk 已经开始新的会话之后响应呢? 我可以试试。我会告诉你的。以上是关于在初始广播消息后向特定 Smack 域发送消息的主要内容,如果未能解决你的问题,请参考以下文章
使用 Smack Api for Android 发送和接收消息