Отправка сообщений в определенные домены Smack после первоначального широковещательного сообщения - PullRequest
0 голосов
/ 22 января 2011

Я создаю клиент обмена мгновенными сообщениями, используя Smack 3.1.0 и Java. Проблема, с которой я сталкиваюсь, связана с отправкой сообщений пользователю в определенном домене.

Например, у меня есть два пользователя: 1@gmail.com и 2@gmail.com. 1@gmail.com входит в XMPP через мой IM-клиент. 2@gmail.com входит в GChat через gmail.com И второй раз через pidgin. Так что теперь у меня есть один экземпляр 1@gmail.com и 2 экземпляра 2@gmail.com.

Как работает gmail, если 1@gmail.com отправляет сообщение на адрес 2@gmail.com, gmail и клиент pidgin оба получают исходное сообщение. Но затем, если экземпляр gmail отвечает на сообщение, каждое сообщение с этого момента идет только между 1@gmail.com и экземпляром gmail 2@gmail.com.

.

Я хотел бы подражать этому поведению с моим IM-клиентом. Я думаю, что способ сделать это будет настроить чат, отправить начальный 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);
    }
});

UPDATE Я хотел дополнить ответ ниже реальным кодом, который использовал для этой работы:

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 объектами, которые, вероятно, могут быть объединены в новый класс. Но это работает.

Ответы [ 2 ]

1 голос
/ 05 сентября 2016

Пока я понял, что 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. Затем отправьте сообщение как обычно.

0 голосов
/ 22 января 2011

В вашем MessageListener почему бы не всегда отвечать отправителю? Я думаю, что вы получаете это, вызывая что-то вроде msg.getSender () или getFrom () (я сейчас на мобильном, не могу проверить)

...