Reputation: 65
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
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
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
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