在初始广播消息后将消息发送到特定的 Smack 域

发布于 2024-10-13 13:11:12 字数 3443 浏览 1 评论 0原文

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

例如,我有两个用户,[email protected][电子邮件受保护][email protected] 通过我的 IM 客户端登录到 XMPP。 [email protected] 通过 gmail.com 登录 GChat 并再次登录通过洋泾浜语。所以现在我有一个 [email protected] 实例和 2 个 < a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="231163444e424a4f0d404c4e">[电子邮件受保护]。

gmail 的工作方式是,如果 [email protected][email protected],gmail 和 pidgin 客户端都会收到初始消息。但是,如果 gmail 实例响应该消息,则此后的每条消息仅在 [email  ;protected][email protected] 的 gmail 实例。

我想用我的 IM 客户端模仿这种行为。我认为做到这一点的方法是建立一个聊天,将初始即时消息发送到收件人的所有实例。然后我会设置一个 MessageListener 来监听响应。当我收到回复时,我必须创建一个新的聊天,指定 [email]受保护]/资源。但这样我就必须编写 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 对象,它们可能会合并到一个新类中。但它有效。

I'm creating an instant messaging client using Smack 3.1.0 and Java. The problem I'm running in to has to do with sending messages to the user on a specific domain.

For example, I have two users, [email protected] and [email protected]. [email protected] logs in to XMPP through my IM client. [email protected] logs in to GChat through gmail.com AND a second time through pidgin. So now I have one instance of [email protected] and 2 instances of [email protected].

The way gmail works, if [email protected] sends a message to [email protected], the gmail and the pidgin client both get the initial message. But then if the gmail instance responds to the message, every message from then on only goes between [email protected] and the gmail instance of [email protected].

I would like to mimic this behavior with my IM client. I would think the way to do it would be to set up a Chat, send the initial IM to all instances of the recipient. Then I'd set up a MessageListener to listen for a response. When I get the response, I'd have to create a new chat, specifying the [email protected]/resource. But then I'd have to write the MessageListener twice. Any ideas? Here's some sample code that I'm using (the method AddText() simply appends the message to my conversation pane):

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);
    }
});

UPDATE
I wanted to supplement the answer below with actual code that I used to make this work:

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);
        }
    }
});

To summarize, I send the first message to all resources of the recipient's address and wait for a response. When I get the response, I replace the current Chat object with a new one that specifies the individual resource that responded to the initial message. The code is a little messy with two different MessageListener objects that could probably be combined into a new class. But it works.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

还如梦归 2024-10-20 13:11:13

到目前为止,我了解到 Message Carbon (XEP - 0280) 将解决您的问题。
如果您启用 Carbon,它会将消息分发到用户的所有已记录资源。在您的情况下,如果 [email protected] 发送邮件至 [email protected] 它将分发到 [电子邮件受保护]
这是使用 smack 的代码示例,

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

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

So far I understood Message Carbon (XEP - 0280) will solve your problem.
If you enable carbon it will distribute messages to all logged resources of a user. In your case if [email protected] send message to [email protected] it will be distributed to all logged resources of [email protected].
Here's a code sample using smack,

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

First make sure that your server is supported Message Carbon.
Then send message as usual.

泪眸﹌ 2024-10-20 13:11:13

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

In your MessageListener why not always respond to the sender? I think you get it by calling something like msg.getSender() or getFrom() (I'm on mobile right now, cannot check)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文