ASmack MultiUserChat ( MUC ) не может прослушать сообщения

У меня есть это приложение для Android, которое я пытался установить XMPP MultiUserChat.

Что касается подключения к XMPP, входа в систему и создания MUC (а также присоединения к уже созданному), все идет нормально.

Мне просто кажется, что я не могу правильно слушать отправленные сообщения, и я не знаю, почему.

Раньше я несколько раз работал с XMPP с использованием Javascript (StropheJS с Bosh), поэтому я немного знаком с его протоколами.

Поскольку я уже пробовал то, что предлагается в следующем сообщении (единственное сообщение, которое я нашел по этому вопросу):

Как правильно прослушивать MultiUserChat в Smack?

Итак, я решил спросить вас о некоторых направлениях, так как я думаю, что это, вероятно, простая установка, которую я все время упускал.

Итак, для простоты я приведу всю свою последовательность.

Я создал службу, поэтому мое соединение XMPP может распространяться на все приложение. Поскольку мне нужно подключиться к XMPP, как только мое приложение войдет в систему, а комнаты MUC будут использоваться только дальше для других действий. Ну, вы поняли картину. Итак, вот код:

(извините, если это слишком длинно, я не хочу раздражать, все, что я хочу, это предоставить все необходимое для ее решения)

//everything is alright here.
//it's connecting correctly to XMPP
public void connect()
{

    Thread t = new Thread(new Runnable() {

        @Override
        public void run()
        {
            boolean flConnected = false;
            System.setProperty("smack.debugEnabled", "true");
            SmackConfiguration.setDefaultPacketReplyTimeout(10000);


            ConnectionConfiguration ConnectionConfiguration = new ConnectionConfiguration(Host, Port);
            ConnectionConfiguration.setSecurityMode(org.jivesoftware.smack.ConnectionConfiguration.SecurityMode.disabled);

            ConnectionConfiguration.setDebuggerEnabled(true);
            ConnectionConfiguration.setSendPresence(true);

            connection = new XMPPTCPConnection(ConnectionConfiguration);

            try
            {
                connection.connect();
                login();
            }
            //there are many exceptions being treated, I 
            //suppressed them here for simplicity's sake
            catch (Exception e)
            {
                Log.e(TAG, "connection exception: " + e.getMessage());
            }


        }
    });
    t.start();
}

public void login()
{
    try
    {
        connection.login(this.User, Pwd);

        Presence presence = new Presence(Presence.Type.available);
        connection.sendPacket(presence);
        this.setLoginAttempts();           

    }
    catch (Exception e)
    {
        Log.e(TAG, "connection exception: "+e.getMessage());
    }
}

Итак, когда пользователь должен быть администратором определенной чат-группы, я создаю группу, передавая GroupName (id)

public void createGroup(String strRoom)
{
    try
    {
        muc = new MultiUserChat(connection, strRoom+"@"+this.GroupChat);
        muc.create(this.User);

        Form form = muc.getConfigurationForm();
        Form submitForm = form.createAnswerForm();



        for (Iterator fields = form.getFields().iterator(); fields.hasNext();) {
            FormField field = (FormField) fields.next();
            if (!FormField.TYPE_HIDDEN.equals(field.getType())
                    && field.getVariable() != null) {
                    submitForm.setDefaultAnswer(field.getVariable());
            }
        }

        List<String> owners = new ArrayList<>();
        owners.add(this.User + "@"+this.Host);

        muc.sendConfigurationForm(submitForm);                        

        //here, it's another FAILED attempt of putting the 
        //listener to an async class. Didn't work at all!!
        //just kept it here so you can see my attempts!
        //new MessageRunner().execute(connection);           

    }
    catch (Exception ex)
    {
        Log.e(TAG, " exception :"+ex.getMessage());
    }
}

А когда он просто участник, он присоединяется к группе:

public void joinGroup(String strRoom)
{
    try
    {
        DiscussionHistory history = new DiscussionHistory();
        history.setMaxStanzas(50);
        muc = new MultiUserChat(connection, strRoom+"@"+this.GroupChat);
        muc.join(strRoom, this.Pwd, history, connection.getPacketReplyTimeout());

        this.addMessageListener(muc);

        this.listen2Group();
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Exception :"+ex.getMessage());
    }
}

Итак, у меня есть 3 метода, которые я использовал как попытки заставить пользователя правильно слушать входящие сообщения.

Один из них устанавливается сразу после входа в систему: setListener(connection);

Два других вызываются после того, как пользователь присоединится к групповому чату:

добавить прослушиватель сообщений (мук); и listen2Group();

Я оставляю их все здесь, чтобы вы могли видеть, как далеко я продвинулся:

private void addMessageListener(MultiUserChat muc)
{
    //it's never coming here! never ever!!!
    if(null != muc){
        muc.addMessageListener(new PacketListener() {
            @Override
            public void processPacket(Packet packet) {
                Log.i("processPacket", "receiving message");
            }
        });
    }
}

private void listen2Group()
{

    //also, NEVER EVER getting here at any time!!
    PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);


    connection.addPacketListener(new PacketListener() {
        @Override
        public void processPacket(Packet packet) throws NotConnectedException
        {
            Message message = (Message) packet;
            if (message.getBody() != null)
            {

                //message should be treated here, 
                //but I suppressed it as well.
            }
        }
    }, filter);
}

public void setListener(XMPPConnection cnx)
{
    this.connection = cnx;
    if (connection != null) {

        PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
        connection.addPacketListener(new PacketListener() {
            @Override
            public void processPacket(Packet packet) {
                Message message = (Message) packet;
                if (message.getBody() != null) 
                {                        
                   //message will be treated here.
                }
            }
        }, filter);
    }

}

И вот как я отправляю сообщения:

public void sendMessage(String msgText)
{
    try
    {

        Message msg = new Message();
        msg.setBody(msgText);
        msg.setType(Message.Type.groupchat);


        muc.sendMessage(msg);

        //I tried sending with this one as well, nope!
        //connection.sendPacket(msg);
    }
    catch(Exception ex)
    {
        Log.e(TAG, " exception :"+ex.getMessage());
    }
}

Итак, наверное, вы уже видели, где я делаю это неправильно. Но я работаю над этим уже несколько дней. Ничего не проходит!

Когда я проверяю свой сервер (openfire), все пользователи находятся в сети, они также правильно регистрируются в MUC, когда сообщения отправляются, ничего не происходит!

Я устанавливаю точки останова на всех слушателях, которые показывал вам, но они никогда не срабатывают, независимо от того, что я делаю. Сообщение отправляется, но никуда не приходит.

Любые идеи?


person Former User of Mine    schedule 17.02.2015    source источник


Ответы (1)


Для будущих ссылок (поскольку smack в его текущей версии не полностью задокументирован)

Я нашел, что не так со слушателями!

Оказывается, я не устанавливал пункт назначения в чат-группу.

Поскольку по своей природе это групповой чат, я предположил, что ему не нужно настраивать получателя для сообщений.

Все, что нужно было, чтобы исправить это, было в моем методе sendMessage, лишняя строка:

msg.setTo(this.room+"@"+my_service_address);

http://xmpp.org/extensions/xep-0045.html

В XEP-0045 указано, что для правильной работы группового чата у него должен быть адрес назначения.

«Сообщения, отправляемые в многопользовательских чатах, относятся к особому типу «групповой чат» и адресуются самой комнате (room@service), а затем передаются всем ее обитателям».

person Former User of Mine    schedule 18.02.2015