Question

I have built an external openfire component based on the Whack library by extending the AbstractComponent class. I want clients to subscribe to my component and receive presence notifications when the component goes online and offline. So my question is how we can deal with presence and presence subscriptions for external component based on AbstractComponent?

Currently I can respond to the presence request by using the handlePresence() method but how do should I add clients to the component roster (does external components allow for roster in the first place)?

@Override
protected void handlePresence(Presence presence){
    if (presence.getType() ==  Presence.Type.subscribe){
        System.out.println("The component has received Subscribtion request.");
        Presence original =  presence;
        Presence response = new Presence();
        //Swap the sender/recipient fields
        response.setTo(original.getFrom());
        response.setFrom(original.getTo());
        //Convert the text to upper case
        response.setType(Presence.Type.subscribed);
        send(response);

    }
}
Was it helpful?

Solution

Components do not have a roster provided by the server. You can store your own roster in a database if you need to. Some applications can get away with no roster at all (when they simply want to appear online to everyone).

To appear online to everyone (simplest approach, no roster storage required):

  • When you receive <presence type="subscribe"/> reply with <presence type="subscribed"/>
  • When you receive <presence type="probe"/> reply with <presence/> (or whatever status you want to be shown as)

To store a roster requires a bit more work, but allows you to keep track of who is authorized to see your presence, and whose presence you are authorized to see. In some cases you might prefer to use a normal client connection here, if you don't want to manage your own roster. Jack Moffitt wrote a blog post on the idea here: http://metajack.im/2008/08/04/thoughts-on-scalable-xmpp-bots/

Note that throughout this post I omit the 'to' and 'from' attributes on stanzas. It is up to the component to put a 'to' and 'from' on outgoing stanzas. All incoming stanzas will have a 'to' and 'from'.

Displaying a component's presence to users

The basic incoming stanzas you need to handle are:

  • <presence type="subscribe">

    • The sender wants to subscribe to your presence updates. You can either approve or decline this. If you approve, you should store the sender's JID in your database so you know you need to send them your presence updates when necessary.
    • Specification: http://xmpp.org/rfcs/rfc6121.html#sub-request-handle
  • <presence type="unsubscribe">

    • The sender wants to stop receiving presence updates from you. You should remove them from the list of people subscribed to your updates, and then send back <presence type="unsubscribed"> and <presence type="unavailable">.
    • Specification: http://xmpp.org/rfcs/rfc6121.html#sub-cancel-inbound (though the text is tailored more towards servers than components here).
  • <presence type="probe">
    • The sender is asking for your current presence. Simply reply with your latest presence stanza for that user. This is typically sent by the user's server when they log in.

Receiving presence of users in a component

Additionally if you want the component to know the presence of users, you need to send a subscription request to them: <presence type="subscribe">. You should be prepared to receive either an approval (<presence type="subscribed">) or denial (<presence type="unsubscribed">).

When the component first comes online, it can fetch the current presence for a user by sending <presence type="probe"> to each user. There is no need to do this more than once per user while the component is running - the user's server will automatically send you presence updates if the user approved your subscription request as above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top