User Resources/Presence

Hi

In Roster.java, I noticed that there’‘s no way I can retrieve the user’'s resources and presences. This information is stored in the Map in presenceMap.get(key). Ie, Map userPresences = (Map) presenceMap.get(key);

There’'s a method getPresences(), but that returns only the presences, I want the resources as well.

I have 2 choices:

(1) Modify fireRosterPresenceEvent() to pass the username AND resource.

(2) Add a getter method for presenceMap.get(key);

Please advise.

Regards

Keith

Hi

I did a bit more digging, and realised that option (2) is not possible, because the fireRosterPresenceEvent() is called after removing the user presence. So, if a buddy (with multiple resources) disconnects, I cannot tell that he has disappeared (for that particular resource).

So, I had to change RosterListener.java from:

public void presenceChanged(String XMPPAddress);

to

public void presenceChanged(String XMPPAddress, String resource);

And Roster.java from:

fireRosterPresenceEvent(key);

to

fireRosterPresenceEvent(key, StringUtils.parseResource(from));

I know this change will break existing code. Please advise is there is a better way to patch the code.

Regards

Keith

Keith,

The presence objects from getPresences(String) includes the resource as the “from” field in the packet. You could use the following code as an example:

Iterator iter = roster.getPresences("user@example.com");
while (iter.hasNext()) {
    Presence presence = iter.next();
    System.out.println("Full JID: " + presence.getFrom());
}

Regards,

Matt

Hi Matt

Your code will not work for logging off, because by the time the presence is dispatched to my code, the resource is already removed. In Roster.java:

else if (presence.getType() == Presence.Type.UNAVAILABLE) {

userPresences.remove(StringUtils.parseResource(from));

fireRosterPresenceEvent(key);

For example, user1/Home and user1/Work log on. My app will receive their available presences fine. But when user1/Home logs off, the resource will be removed by the time it reaches me. The resource needs to be attached to the event for complete tracking of resources presence. I have replaced the line

fireRosterPresenceEvent(key);

with

fireRosterPresenceEvent(key, StringUtils.parseResource(from));

I would prefer not to maintain my own code branch of Smack, any help to fix my problem would be greatly appreciated.

Regards

Keith

Keith,

Ahh, I understand the problem you’'re running into now. I think the right fix is to just make:

public void presenceChanged(String XMPPAddress);

include the resource as part of address. This change doesn’‘t violate the API spec and the current behavior is really a bug. I’'ll file a bug in the issue tracker to get this fixed for the next release.

Thanks,

Matt

This issue is now fixed – SMACK-28.

Hi Matt

Thank you very much for your fix!

Well done.

Keith