Jabber Next-Gen


Described here is the next generation protocol that builds upon the powerful heritage of the original Jabber routing and streaming protocols while also eliminating their shortcomings.

The basic concept is built around streams and identities, every stream connection is assigned a unique temporary identity.  Each stream also wraps all routeable xml and does no parsing of it's contents.  There is only one stream namespace, and no namespaces are used or parsed within the routing layer.


Stream Namespace

First, we send:

    <jabber xmlns="jabber:root">

Response:

    <jabber xmlns="jabber:root" jid="guid@ccm1.foo.net">

The stream then consists of a few basic elements, the most important being the <route/>.  Each route can contain any child elements in any namespace.  The sender and recipient of the route must be a valid Jabber ID.  Every stream has at least one such id associated with it as given in the root element, and only the associated ids may be used as a sender.  Additional sender ids are bound to the stream as requested and authorized.  Streams can also perform chunking, or breaking apart large elements so that additional elements can be delivered simultaneously.

The jabber root namespace contains the following elements:

State Preservation

When entities are interacting through Jabber they will often create state that is dependent upon the existence of the stream.  In the original protocol this very important feature was fundamentally built in and not extensible, that when a (client only) socket was broken, the session manager would internally be notified and be responsible for notifying anyone subscribed to their presence.

State can easily be preserved in this new protocol in a generic and extensible way.  When the sender needs to send something that may require the recipient to have knowledge of a change in the connection state (such as sending status/availability information), it first sends the route and children elements that would be delivered upon a disconnect, in a parent route to the given primary stream jid.  When the other end of the stream receives a route to it's own jid, it stores the children routes in a queue using the first route's id attribute as a unique key.  The queue is then processed upon disconnect and all stored routes are delivered.  If the state changes before disconnect, or the recipient no longer needs to be notified, another route with the same id is sent with no children, which would empty anything in the queue based on that id key.

Discussion


Fundamental problems fixed:
All session creation, presence management, and other services and application logic are independent from this fundamental routing layer.


Examples


A message (after we've bound to a jid):
    <route to="foo@jabber.org" from="jer@jabber.org/bar">
        <message xmlns="jabber:message" type="chat"><body>heya</body></message>
    </route>

Multiples:
    <route to="bar.net" from="jer@jabber.org/bar" id="q0">
        <foo xmlns="http://foo.org/foo.dtd"><do>...</do></foo>
        <bar xmlns="http://bar.net/bar.dtd"/>
    </route>

Responses:
    <route to="jer@jabber.org/bar" from="bar.net" id="q0">
        <foo xmlns="http://foo.org/foo.dtd"><done/></foo>
    </route>
    <error to="jer@jabber.org/bar" from="bar.net" code="501" id="q0">
        <bar xmlns="http://bar.net/bar.dtd"/>
    </error>

A forwarded message:
    <route from="jer@home.jeremie.com" to="jer@jabber.org/bar">
        <route from="foo@bar.net" to="jer@jabber.org">
            <message xmlns="jabber:message" type="chat"><body>heya</body></message>
        </route>
    </route>