AnsweredAssumed Answered

Initial login presence being missed, Roster instantiation too late

Question asked by philwinder on Oct 20, 2014
Latest reply on Oct 21, 2014 by philwinder

Florian, all,

I've noticed during my debugging that the initial Presence updates sent by the server are being missed because the Roster is instantiated too late. Below is the output from the Smack debug mode. Grace has one user in her roster, Hubert. We can see that after the stream setup has completed, the user Grace is logged in and smack sends an empty presence. Right after this, the server sends the initial presence messages of the users on her roster. These are not captured by smack because the listeners haven't been added by the Roster instantiation. I have debugged to make sure. After the presence messages, the roster request is sent (this is the point in time where the Roster is initialised). Note that subsequent presence notifications after this point are parsed correctly.

 

I seem to have this problem more when debugging (because the debugging process and println statements slow down the instantiation), but it does happen when not debugging too. I guess it depends how fast the server responds and how quick the connection is.

 

I'm not sure what the solution is here. Is there any way you could move the roster initialisation to before the final login message is received? Also, I can't seem to find a way to re-request that the server sends those initial presences again, so I can't provide a workaround either.

 

Update: it is possible to force the server to re-send the initial presence updates by simulating a log out and log in. I.e. send two presence packets, unavailable then available. This will trick the server into resending all the presences in your roster. Obviously, this is very hacky, but it works around the problems stated above.

 

Update 2: An even better solution is to force the instantiation of the roster after connection, but before login. Pseudocode: con.connect(); con.getRoster(); con.login("myUser","host", "resource");. This way the roster can set up it's listeners before the user is actually connected.

 

Ideas welcome.


Thanks,

Phil

 

Ps. Output from smack debug. The key here is that the presences packets are sent and received before smack has had time to instantiate the roster.

...

D/SMACK﹕ SENT (0): <iq id='2Y6Ex-3' type='set'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>

D/SMACK﹕ RCV (0): <iq type='result' id='2Y6Ex-3'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>

D/SMACK﹕ User logged (0): grace@localhost/localhost@localhost:5222

D/SMACK﹕ SENT (0): <presence id='2Y6Ex-5'></presence>

D/SMACK﹕ RCV (0): <presence from='grace@localhost/localhost' to='grace@localhost/localhost' xml:lang='' id='2Y6Ex-5'/><presence from='hubert@localhost/localhost' to='grace@localhost/localhost' xml:lang='' id='LXAzl-5'><delay xmlns='urn:xmpp:delay' from='hubert@localhost/localhost' stamp='2014-10-20T10:37:18Z'></delay><x xmlns='jabber:x:delay' stamp='20141020T10:37:18'/></presence>

D/SMACK﹕ SENT (0): <iq id='2Y6Ex-8' type='get'><query xmlns='jabber:iq:roster'></query></iq>

D/SMACK﹕ RCV (0): <iq from='grace@localhost' to='grace@localhost/localhost' id='2Y6Ex-8' type='result'><query xmlns='jabber:iq:roster'><item subscription='to' name='hub' jid='hubert@localhost'/></query></iq>

Outcomes