Haf
Haf

Reputation: 65

How to find out the room occupants when someone joined or left a MultiUserChat in smackx?

I am trying to implement a MultiUserChat with the smackx api.

So far I managed to create a new MultiUserChat room, join it, and send invites out. My problem as of now is how to find out who is in the chat room if someone joined the chat room or left it. I thought that adding a presence listener to the chat room might do the trick:

muc.addParticipantListener(new PacketListener() {

    @Override
    public void processPacket(Packet packet) {
        System.out.println("user count changed, now:" + muc.getOccupcantsCount());
    }
});

The Javadoc for addParticipantListener states

Adds a packet listener that will be notified of any new Presence packets sent to the group chat. Using a listener is a suitable way to know when the list of occupants should be re-loaded due to any changes.

So I thought that this would work. However, within the processPacket method muc.getOccupantsCount() as well as muc.getOccupants() both return the values BEFORE the processPacket call. So if there is only one user in the chat room and another joins, the output will be

user count changed, now: 1

If there are two users and another joins, the output is

user count changed, now: 2

And if there are three users and one leaves, the output is

user count changed, now: 3

Respectively, muc.getOccupants() won't give me the user that just joined when called within processPacket, and still gives me the user that just left.

How can I effectively find out who currently is in the chat room from within processPacket?

Upvotes: 4

Views: 3037

Answers (3)

Z. Mei
Z. Mei

Reputation: 31

For your new question that how we can initialize MultiuserChat if don't have a room name, I find the source code of MultiUserChat, and only a constructor is declared:

 public MultiUserChat(Connection connection, String room) {
        this.connection = connection;
        this.room = room.toLowerCase();
        init();
    }

Upvotes: 0

Lemontree
Lemontree

Reputation: 11

It's a good question, and find the the deficiencies in the practical effects of these methods (e.g. getOccupants(),getOccupantsCount()).

As you see, the key problem is that PacketListeners is unable to response in time. SO what you need is to detect user status activity. Using the Presence to detect the status of users is a effective method to ensure the timely updating of user information. Moreover, there may exist other ways to achieve it.

Upvotes: 0

Flow
Flow

Reputation: 24043

You can't. Not within a PacketListener and muc.getOccupantsCount().

The occupant count is also determined by using a PacketListener within smackx. And it's not guaranteed that this PacketListener is run before yours and has therefore a chance to update the occupant count.

One way to solve it right now is to examine the presence packet and cross-check it with the current member list. Basically doing the same as the built-in presence listener. Or you could artificially delay the action so that all PacketListeners have a chance to finish.

I have created SMACK-424 to track this issue in Smack.

Upvotes: 3

Related Questions