MultiUserChat.leave() not working for me

Hello all,

I am attempting to have a user leave a muc with the following method:

//THIS METHOD WILL CAUSE A USER TO LEAVE A MULTI USER CHAT, CALLED FROM AN ONCLICK EVENT

public void leaveExistingMUC(Object conn, String room)

{

XMPPConnection connx = (XMPPConnection) conn;

MultiUserChat muc = new MultiUserChat(connx,room);

muc.leave();

System.out.println(“METHOD LEAVEEXISTINGMUC CALLED”);

}

/code

The method is actually called but the user never actually “leaves” the muc…ie, he still shows up in the wifi admin console.

Am I using this method incorrectly?

TIA!

Hi,

leaving a MUC does not close the XMPP connection. So do you see this user still in the MUC or just in the admin console as logged in.

LG

Thanks LG,

I still see this person (or rather , the count in the room remains the same).

Funny thing is …if I use the same method that I use to join an existing muc…and then Thread.sleep(4000) and then call muc.leave() it works.

I modified my code some…

//THIS METHOD WILL CAUSE A USER TO LEAVE A MULTI USER CHAT

public void leaveExistingMUC(Object conn, String room_name)throws XMPPException

{

MultiUserChat muc = null;

try

{

XMPPConnection connx = (XMPPConnection) conn;

muc = new MultiUserChat(connx,room_name);

if(muc.isJoined()){

muc.leave();

}

else{

}

catch(Exception e){e.printStackTrace();}

}

/code

Unfortunately, muc.isJoined() always returns false.

I also to join the muc if isJoined() returned false…this works but I get the “user just joined” and “user just left” back to back from my listener.

I am creating my muc object exactly as I create it when I join an existing room so thats not the problem.

I also tried to change the room_name string to be :

user1

user1@conference.localhost.locadomain

user1@conference.localhost.localdomain/Smack

When the user initially joins I print out the connection.getUser().

When I call the leave muc I do the same.

These values are identical.

Any ideas?

TIA!

According to MultiUserChat.java, there’‘s a “joined” boolean variable that’'s initialized to false when you create it a MultiUserChat object. This variable is checked when you call leave() and returns without doing anything if found false.

Currently I’'m leaving mucs by keeping the references of the joined rooms. You can then later retrieve the corresponding room using the room_name (say, from a hashtable) and call .leave() on that muc object.

HTH.

Seems that the problem may be related to the muc object.

//THIS METHOD WILL CAUSE A USER TO LEAVE A MULTI USER CHAT

public void leaveExistingMUC(Object conn, String room_name)throws XMPPException

{

MultiUserChat muc = null;

try

{

XMPPConnection connx = (XMPPConnection) conn;

muc = new MultiUserChat(connx,room_name+CONFERENCE_SERVICE_NAME);

/code

When I instantiate a new MultiUserChat it seems that I have a reference to a totally different muc object than is expected…

If I do a muc.getOccupantsCount()

it returns a different count than what the wifi admin console reflects.

Dont know how this is possible. As I said, I have tried to use many variations while instantiating the object…

muc = new MultiUserChat(connx,“aroom”);

muc = new MultiUserChat(connx,“aroom@conference.localhost.localdomain”);

/code

I really need to be able to have the user leave the room “cleanly” without having to lose the XMPPConnection.

Is there a way to explicitly remove a user from a muc?

TIA!

Perhaps the problem lies within the following:

Here is my code that allows a user to join an existing muc:

//ALLOW A USER TO JOIN AN EXISTING MULTI USER CHAT ROOM

public MultiUserChat joinExistingMUC(Object conn,String room_name)

{

MultiUserChat muc = null;

try

{

XMPPConnection connx = (XMPPConnection) conn;

muc = new MultiUserChat(connx,room_name+CONFERENCE_SERVICE_NAME);

DiscussionHistory history = new DiscussionHistory();

history.setMaxStanzas(200);

System.out.println(“JOINED EXISTING AS:”+connx.getUser());

muc.join(connx.getUser(),“password”,history,SmackConfiguration.getPacketReplyTi meout());

}

catch(XMPPException xmpe){xmpe.printStackTrace();}

return muc;

}

/code

Now if you notice, I join the muc as XMPPConnection.getUser() which is gforty@localhost.localdomain/Smack.

Now here is my leave method again:

//THIS METHOD WILL CAUSE A USER TO LEAVE A MULTI USER CHAT

public void leaveExistingMUC(Object conn, String room_name)throws XMPPException

{

MultiUserChat muc = null;

try

{

XMPPConnection connx = (XMPPConnection) conn;

muc = new MultiUserChat(connx,room_name);

System.out.println(“IS JOINED***********************”+muc.isJoined()); //THIS RETURNS FALSE

if(muc.isJoined()){

muc.leave();

}

else{

System.out.println(“Not joined”);}

}

catch(Exception e){e.printStackTrace();}

}

/code

So muc.isJoined() returns false.

So how is leave() called?

From SVN

429 public synchronized void leave() {

430 // If not joined already, do nothing.

431 if (!joined) {

432 return;

433 }

434 // We leave a room by sending a presence packet where the “to”

435 // field is in the form “roomName@service/nickname”

436 Presence leavePresence = new Presence(Presence.Type.UNAVAILABLE);

437 leavePresence.setTo(room + “/” + nickname);

438 connection.sendPacket(leavePresence);

439 // Reset participant information.

440 participantsMap = new HashMap();

441 nickname = null;

442 joined = false;

443 userHasLeft();

444 }

/code

Does the leavePresence.setTo method get its room and nickname from the connection object?

TIA!

OK,

to get around this issue for now it seems that I have to create the muc object and then re-join the room. SLOPPY.

Here is what I have to do:

User 1 gets a XMPPConnection

User 2 gets a XMPPConnection

User 1 joins an existing (persistent) MUltiUserChat called “aroom” using XMPPConnection.getUser() as the nick.

User 2 joins an existing (persistent) MUltiUserChat called “aroom” using XMPPConnection.getUser() as the nick.

User 1 receives a message (from ParticipantStatusListener) “User 2 has joined the room”.

they chat.

User 1 decides to leave the chat calling my method.

My method creates a new MultiUserChat object using: muc = new MultiUserChat(connx,[aroom@conference.localhost.localdomain|mailto:aroom@confer ence.localhost.localdomain]);

at this point if I do a isJoined() I get false, Even though the Wildfire admin tells me that there are 2 users in conference room called aroom.

so I call muc.join(XMPPConnection.getUser()).

User 2 receives a message (from ParticipantStatusListener) “User 1 has joined the room”.

User 1 receives a message (from ParticipantStatusListener) “User 1 has joined the room”.

then I do a :

Thread.sleep(19000);

During the Thread.sleep, I constantly refresh the wifi admin console to see if 3 users show up (doesnt only shows 2 the entire 19 seconds).

I then call

muc.leave().

User 2 receives another message (from ParticipantStatusListener) “User 2 has left the room”.

User 1 receives a message (from ParticipantStatusListener) “User 1 has joined the room”.

As I said, Sloppy.

How is this possible.?

Why am I having to rejoin only to call the leave method?

TIA!!

gforty wrote:

My method creates a new MultiUserChat object using: muc = new MultiUserChat(connx,[aroom@conference.localhost.localdomain|mailto:aroom@confer ence.localhost.localdomain]);

at this point if I do a isJoined() I get false, Even though the Wildfire admin tells me that there are 2 users in conference room called aroom.

That is your problem. The isJoined() method doesn’‘t do an actual lookup; it just returns a member variable of the MultiUserChat object you just created, so I’‘d expect it to be false. I’'d recommend keeping your MultiUserChat objects around in a data structure in your client memory.

I suppose Smack could make this easier by making the constructor private and adding factory create and/or retrieval methods. In the meantime my solution should suffice.

Jeff

jsegal wrote:
gforty wrote:

My method creates a new MultiUserChat object using: muc = new MultiUserChat(connx,[aroom@conference.localhost.localdomain|mailto:aroom@confer ence.localhost.localdomain]);

at this point if I do a isJoined() I get false, Even though the Wildfire admin tells me that there are 2 users in conference room called aroom.

That is your problem. The isJoined() method doesn’‘t do an actual lookup; it just returns a member variable of the MultiUserChat object you just created, so I’‘d expect it to be false. I’'d recommend keeping your MultiUserChat objects around in a data structure in your client memory.

I suppose Smack could make this easier by making the constructor private and adding factory create and/or retrieval methods. In the meantime my solution should suffice.

Jeff

Yep keeping the muc objects around is what I suggested too, but it seems the suggestion has been ignored totally

Thanks fellows,

I actually tried this last thing yesterday…

The reason I hesitated was bc my app is web-based and I was already storing the connection in the session and wanted to limit what was stored there.

I stored the muc object as suggested, and it worked fine.

I just couldnt understand why the muc.leave (as I was using it, would not work)…

Thanks Stupidboi and Jeff