PEP(Personal Eventing Protocol) with Smack

Personal Eventing Protocol (aka PEP) is a really nice pubsub feature on the Jabber platform. It allows you to publish information regarding yourself to your friends in your roster, like what Facebook. The XMPP community calls this rich presence.

I’ve been wanting to play with this feature so I started a little project to look into this. I’ll publish what games I’m playing using a yet unapproved XMPP specs call User Gaming (XEP-196). There are really 2 pieces to this little exercise:

  1. The low level bit which includes
    • Setting up data in the correct XML document/fragment and then send this out via Smack
    • Configuring Smack with the correct parser for your XML document; this is call a provider in Smack terminology. Parsing is required on the recipient side
  2. Using the high level Smack API to publish and receive incoming PEP messages

This will be a 3 part blog with this part focusing on creating the PEP item and sending it.


Get the latest copy of Smack from the repository. You need to get the source because we will need to make 2 small changes to Add the keyword public to lines 36, 37 like so

public abstract String getNode();
public abstract String getItemDetailsXML();

then recompile and use the new smackx.jar.

Creating PEP Payload for Publishing

To publish a PEP item, we need to know the structure of the XML document; here is how a typical out going (viz. publish) looks like

<pubsub xmlns=””&gt;
   <publish node=”urn:xmpp:gaming:0″>
      <item id=”m3GYKa7jNiXf800pJ8cr”>
         <game xmlns=”urn:xmpp:gaming:0″>


Our responsibility is to generate the bits in red and green. The <game> is User Gaming and <item> is the envelope. The following code snippet shows how we use JAXB to generate the <game> fragment:

@XmlRootElement(name=Game.ELEMENT_NAME, namespace=Game.NAMESPACE)
public class Game {
   public static final String ELEMENT_NAME = “game”;
   public static final String NAMESPACE = “urn:xmpp:gaming:0”;
   private String characterName;   
   @XmlElement(name=”character_name”, namespace=Game.NAMESPACE)
   public String getCharacterName() {
      return characterName;
   public void setCharacterName(String characterName) {
      this.characterName = characterName;
   public String toXML() {
      String result = “<game/>”;
      try {
         JAXBContext context = JAXBContext.newInstance(Game.class);
         Marshaller gameMarshaller = context.createMarshaller();
         //Do not generate the XML declaration
         gameMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
         StringWriter sw = new StringWriter();
         gameMarshaller.marshal(this, sw);
         result = sw.toString();
      } catch (Exception e) {
         Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, “toXML()”, e);
      return (result);

I’ve used toXML() instead of toString() to produce the XML fragment; this is in keeping with the conventions used in the Smack library.

Next up, we need to create the <item> wrapper. The following code snippet shows this:

public class GameItem extends PEPItem {
   private final Game game = null;
   private final String id;
   public GameItem(String i, Game g) {
      id = i;
      game = g;
   public String getId() {
      return (id);
   public String getNode() {
      return (Constants.Game.NAMESPACE);
   public String getItemDetailsXML() {      
      return ((game != null)? game.toXML(): “<game/>”);

Some salient points about GameItem class

  1. You MUST extend PEPItem. The reason is that when you publish a PEP item, the publish() will only publish PEPItem type object. That is why you must also make the modification to file (above), otherwise you would not be able to publish anything!
  2. For some strange reason, PEPItem does not allow you to get access to the id. On some protocol like user gaming, you use the same id to cancel a previous item. So its a good idea to add a getId(). Smack also has a handy utility to generate id strings. See StringUtils.randomString().
  3. getNode() method returns the name of the node. In PEP, this is typically the same as the namespace of the object. See One Node Per Namespace.
  4. getItemDetailsXML() returns <game> document.

Here is a how everything fits together

<pubsub xmlns=””&gt;
   <publish node=”urn:xmpp:gaming:0“>  <—- getNode()
      <item id=”m3GYKa7jNiXf800pJ8cr“> <—- id from GameItem/PEPItem
         <game xmlns=”urn:xmpp:gaming:0″>
            <character_name>Sentor</character_name> <— everything in blue from getItemDetailsXML()




To publish a PEP item, create an instance of PEPManager, and invoke publish().

//Create an instance of PEPManager from a XMPPConnection
XMPPConnection conn = …
PEPManager mgr = new PEPManager(conn);

//Create an instance of Game and GameItem
Game game = new Game();

GameItem item = new GameItem(StringUtils.randomString(7), game);

//Now publish it

My next blog will look into receiving PEP messages. Happy hacking.


10 Responses to PEP(Personal Eventing Protocol) with Smack

  1. Freek says:

    Thanks a lot for this tutorial, it helped me a lot!


    Freek – The Netherlands

  2. Luke says:

    Hello, thanks for your tutorials;
    how can I recompile smackx.jar ?

  3. Luke says:

    Constants is a class, I found it !
    I have another question: this implementation sends the PEP information only to friends (users in roaster); is there a method to send information to all users or is a PEP limit ?

  4. Ricardo says:

    Hey great tutorial, I have spent days trying to recompile the smack library after making the variables public. Do you have any tips on how to recompile, I am new to java/android programming. Or do can you share the source code?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: