Problems with MUC - join() and getOccupants()

I am developing a MUC implementation on top of Smack. For the most part everything works fine, but I’'m stumped by the following problem.

Here’'s the use case:

  • jid1 invites to jid2 to ConfA (jid1 is using Spark, so I treat it as a reference implementation)

  • jid2 receives invite via InvitationListener impl and (after user input) executes the following code:

muc = new MultiUserChat(conn, room);

if (password != null)

{

muc.join(jid1, password);

}

else

{

muc.join(jid1);

}

What happens next is that both a conference window and single user chat window pop up. The conference window shows zero occupants. The chat window shows a single, empty message from the jid of the conference room.

In my logs I see the following:

  • The muc is created and joined without any exceptions.

  • The call to muc.getOccupants() returns no occupants (even though 1+ occupants are in the room)

  • I see ChatManagerListener fire a ChatCreated based on a message from ConfA

This is the normal experience. The other experience I see is that the InvitationListener is not fired at all, and all I see is the ChatCreation.

Any thoughts on what might be going on here?

Thanks,

Dan

Make sure that the first user created the room ahead of time using code similar to this example:

Multi User Chat Docs

In particular that create() was called as well as sending the default form in addition to just constructing the object.

The second user can just create the object and call join.

Now the other thing to check is that both the create method and join method take a nickname as a parameter, not a jid. So when you are creating or joining a room you need to pass in a nickname for the current user only. Another thing is that getOccupants() does not always work reliably, especially during room construction, since it is only a single snapshot in time. So often what happens is that at the exact moment you call that method, the data hasn’'t reached your client yet for a few more milliseconds. Therefore, it is better to listen for presence packets to determine who is currently in the room.

Chris

Thanks Chris. In this case, I was testing with persistent rooms, so it wasn’‘t a creation issue, and I was setting up as you suggested. I think it’‘s probably related to the race condition with getOccupants(). I’'ll have to take a closer look at that section and maybe retool it.

Appreciate the help.

Cheers,

Dan

I think I have a handle on the getOccupants() issue, but the join() issue is still kicking my butt. Any ideas?

I don’'t have any specific suggestions for you, but a few general things I discovered while implementing MUC in my client.

  • I thought I had the single user chat popup for MUC when I was accidentally passing in JIDs to join instead of nicknames, if you already checked that then I’'m not sure.

  • Most of my problems came from not getting the timing right. For example, you can’‘t join the room or send out invitations until the room is completely created successfully. So I was running some of this stuff in background threads to avoid locking the GUI and then it would cause problems if I didn’‘t have the sequence of events right. Also, make sure you are attaching the appropriate listeners early enough so that you don’'t miss events. There were several times when I thought I was not getting packets, when in fact I was just missing the callbacks. Using the smack debugger here to verify whether the data is getting to your client helps a lot.

  • Finally, I could never get the built-in MUC listeners to work reliably. The participant status listener and invitation listener, etc. would not always work right for me once I joined and left a room. Therefore, the only workable solution I could find was to do it the way Spark does, which is to use a general packet listener instead of using the MUC listeners.

If none of that sparks any ideas for you, then try posting some more code, particularly including the data you are using as the parameters so I can see if anything looks strange.

Regards,

Chris