How to use ejabberd's pubsub module

This page describes how to use ejabberd's mod_pubsub, an implementation of XEP-0060. It does not describe how to use PEP (XEP-0163). It is also supposed that you have a Jabber client that supports Pubsub (as opposed to PEP), or are prepared to craft and send the stanzas by hand.

Pubsub nodes are organized in a hierarchical tree, similar to a file system. mod_pubsub imposes a special structure on this tree. There is a special node, pubsub/nodes, that contains all other created nodes. Nodes of users have names like home/server/username/whatever. If you try to create a node whose name doesn't fit that pattern, you will get an error. If you don't specify a name (i.e. create an instant node), the server generates a name that fits this pattern.

Example for 2.0.5 with plugin "default". The account "user@localhost" creates his first node:

<iq type="set" to="pubsub.localhost" id="create1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <create node="/home/localhost/user"/>
    <configure/>
  </pubsub>
</iq>
The server answer is:
<iq from='pubsub.localhost'
	id='create1'
	type='result'
	to='user@localhost/work'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create node='/home/localhost/user'/>
  </pubsub>
</iq>

Example for 2.1.0 with plugin "flat". The account "user@localhost" creates a node:

<iq type="set" to="pubsub.localhost" id="create1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <create node="node123"/>
    <configure/>
  </pubsub>
</iq>
The server answer is:
<iq from='pubsub.localhost'
	id='create1'
	type='result'
	to='user@localhost/Home'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create node='/node123'/>
  </pubsub>
</iq>

Then he publishes an item with an ItemID:

<iq type='set'
    to='pubsub.localhost'
    id='publish1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='node123'>
      <item>
        <entry xmlns='http://www.w3.org/2005/Atom'>
          <title>Soliloquy</title>
          <summary>
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles,
And by opposing end them?
          </summary>
          <link rel='alternate' type='text/html'
                href='http://denmark.lit/2003/12/13/atom03'/>
          <id>tag:denmark.lit,2003:entry-32397</id>
          <published>2003-12-13T18:30:02Z</published>
          <updated>2003-12-13T18:30:02Z</updated>
        </entry>
      </item>
    </publish>
  </pubsub>
</iq>
The server answer is:
<iq from='pubsub.localhost'
	to='user@localhost/work'
	id='publish1'
	type='result'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='/node123'>
      <item id='4E3C55905D1A9'/>
    </publish>
  </pubsub>
</iq>

Related links

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Maybe an example is in order ...

When I tried to create an instant note I had to learn the hard way that <configure> must not be empty.

I would very much appreciate an example showing the stanzas flowing back and forth for the following cases:

* Creation of an instant node

* Creation of a named node

* Publishing to a node

* Subscribing to a node

The XEP-060 is not so useful for this, because for example this does not run :

<iq type='set'
    from='hamlet@denmark.lit/elsinore'
    to='pubsub.shakespeare.lit'
    id='create2'>
    <pubsub xmlns='http://jabber.org/protocol/pubsub'>
      <create/>
      <configure/>
    </pubsub>
</iq>

Best wishes

Norbert

pubsub examples

Hi Norbert,

The following work for me:

- instant nodes:

<iq type="set" from="test@minden-203-90.resnet.brown.edu"
    to="pubsub.minden-203-90.resnet.brown.edu" id="create2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <create/>
    <configure/>
  </pubsub>
</iq> 
 
<iq from="pubsub.minden-203-90.resnet.brown.edu"
    to="test@minden-203-90.resnet.brown.edu/SamePlace" id="create2" type="result">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <create node="/home/minden-203-90.resnet.brown.edu/test/2675892619"/>
  </pubsub>
</iq>

- named node:
<iq type="set" from="test@minden-203-90.resnet.brown.edu"
    to="pubsub.minden-203-90.resnet.brown.edu" id="create1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <create node="/home/minden-203-90.resnet.brown.edu/test/norbert_node"/>
    <configure/>
  </pubsub>
 
<iq from="pubsub.minden-203-90.resnet.brown.edu"
    to="test@minden-203-90.resnet.brown.edu/SamePlace" id="create1" type="result">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <create node="/home/minden-203-90.resnet.brown.edu/test/norbert_node"/>
  </pubsub>
</iq>

- subscribe to node

<iq type="set" from="test@minden-203-90.resnet.brown.edu"
    to="pubsub.minden-203-90.resnet.brown.edu" id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe node="/home/minden-203-90.resnet.brown.edu/test/norbert_node"
               jid="test@minden-203-90.resnet.brown.edu"/>
  </pubsub>
</iq>
   
<iq from="pubsub.minden-203-90.resnet.brown.edu"
     to="test@minden-203-90.resnet.brown.edu/SamePlace" id="sub1" type="result">
  <subscription node="/home/minden-203-90.resnet.brown.edu/test/norbert_node"
                jid="test@minden-203-90.resnet.brown.edu" subscription="subscribed" subid="4B8D779397046"/>
</iq>

<message from="pubsub.minden-203-90.resnet.brown.edu"
         to="test@minden-203-90.resnet.brown.edu">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="/home/minden-203-90.resnet.brown.edu/test/norbert_node"/>
  </event>
</message>

- publish to node
 
<iq type="set" to="pubsub.minden-203-90.resnet.brown.edu" id="publish1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <publish node="/home/minden-203-90.resnet.brown.edu/test/norbert_node">
      <item>Hi Norbert!</item>
    </publish>
  </pubsub>
</iq>
 
<iq from="pubsub.minden-203-90.resnet.brown.edu"
    to="test@minden-203-90.resnet.brown.edu/SamePlace" id="publish1" type="result">
</iq>
 
(this is the response, because I am subscribed to the node)
<message from="pubsub.minden-203-90.resnet.brown.edu"
         to="test@minden-203-90.resnet.brown.edu">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="/home/minden-203-90.resnet.brown.edu/test/norbert_node">
      <item id="4B8D78BB7D4E9">Hi Norbert!</item>
    </items>
  </event>
</message>

General pubsub nodes

So if any user can only create nodes under /home/myhost/username,
how can nodes be added under /pubsub/nodes ?

How can I find out the owner of a node under /pubsub/nodes ?

Two other interesting points that don't exactly leap out of the spec:

  • a structured name implies the parent collection as a tree:
    i.e. /home/myhost/username/foo implies pubsub#collection property
    /home/myhost/username without having to add this to the config
    (in fact, you must not include pubsub#collection in create,
    because it is error modify 406 not-acceptable)
  • pubsub#node_type appears to be mutable !?
    e.g. when ejabberd is installed, the /home/myhost and /pubsub/nodes
    have pubsub#node_type leaf, but then you can add nodes
    underneath, and the type switches to collection !

ejabbered advertises feature pubsub#delete-nodes and it should be supported,
because it does support pubsub#create-nodes (XEP-0060 Section 8.4) ,
but any attempt to delete a node returns error 501 cancel feature-not-implemented.

.. and the weirdest behaviour is that each user has to create
an instant node before they can create a named node !?!?
(first attempts to create a named node get error auth 403 forbidden)

Mik

P.S.I. without Psi XML console it would have been impossible to figure this all out - Psi rocks !

P.P.S. All comments refer to ejabbered 2.0.1

Re: General pubsub nodes

I have upgraded to 2.0.5 and it is better - good job.

I see my mistake with delete - I was not using the pubsub#owner namespace. It is very confusing that create (and configure when used with a create) use the raw pubsub namespace, but all other owner operations (including configure when used on its own) use the pubsub#owner namespace. This means there are two distinct pubsub elements, two distinct configure elements, etc., causing confusion in the spec, duplication in the schemas, then additional complexity and confusion in any databinding APIs (e.g. require two PubSub packet extension classes). Oh well, at least my code works now.

The only remaining issue I see is that when a last published item is sent on subscription, it does not contain the <delay xmlns='urn:xmpp:delay' ... as suggested in the spec, but this is a minor issue.

Mik

Try 2.0.5. Or better: try trunk svn.

> All comments refer to ejabberd 2.0.1

There were many bugfixes related to PubSub in ejabberd 2.0.x releases after 2.0.1. And there will be many improvements in ejabberd 2.1.0 once released. So, maybe some of the problems and annoyances you found in 2.0.1 are solved in 2.0.5 or will be solved in 2.1.0.

You can try ejabberd from trunk SVN to verify if those problems are still present in the development version.

Hi itay, I have sent the

Hi itay,

I have sent the same messages to my local ejabberd server (replaced minden-203-90.resnet.brown.edu to localhost).

It nearly works the way it should. The only problem is that it does not send (change event notification) message to the subscribers when the publisher changes the value of the item.

Though it sends the current state of the item when the subscriber logs into the jabber server.

I have tried with two versions of ejabberd:
- the ejabberd-2.0.0 binary version from ejabberd home
- the one packaged in ubuntu hardy - I could not find which version it is exactly(on 2008 may 12)

Have I made a mistake or is it a function that only works in later (development) version of ejabberd?

Syndicate content