The protocol sequence below is derived from an exchange between instances of
my app. Typos could have crept in during editing!

There are features missing... breaking up publish messages to fit the max
size for the node's payload, and types for diff formats.

I look forward to feedback!


1. Creator makes a pubsub node for incoming messages, and subscribes to it:
(These nodes give us IQ for 1-to-1 messaging, even if recipient is offline.)

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9365' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create node='creator'/>
    <configure><x xmlns='jabber:x:data' type='submit'>
      <field var='FORM_TYPE' type='hidden'><value>
http://jabber.org/protocol/pubsub#node_config</value></field>
      <field var='pubsub#notify_retract'><value>0</value></field>
      <field var='pubsub#persist_items'><value>0</value></field>
      <field var='pubsub#publish_model'><value>open</value></field>
      <field var='pubsub#access_model'><value>whitelist</value></field>
      <field
var='pubsub#send_last_published_item'><value>never</value></field>
</x></configure></pubsub></iq>

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9366' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='creator' jid='crea...@localhost/reprev'/>
</pubsub></iq>


2. Contributor does the same:

<iq from='contribu...@localhost/reprev' to='pubsub.localhost'
    type='set' id='8776' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create node='contributor'/>
    <configure><x xmlns='jabber:x:data' type='submit'>
      <field var='FORM_TYPE' type='hidden'><value>
http://jabber.org/protocol/pubsub#node_config</value></field>
      <field var='pubsub#notify_retract'><value>0</value></field>
      <field var='pubsub#persist_items'><value>0</value></field>
      <field var='pubsub#publish_model'><value>open</value></field>
      <field var='pubsub#access_model'><value>whitelist</value></field>
      <field
var='pubsub#send_last_published_item'><value>never</value></field>
</x></configure></pubsub></iq>

<iq from='contribu...@localhost/reprev' to='pubsub.localhost'
    type='set' id='8777' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='contributor' jid='contribu...@localhost/reprev'/>
</pubsub></iq>


3. Creator makes a pubsub node for a shared collection, and subscribes:

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9367' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create node='uuid1.105'/>
    <configure><x xmlns='jabber:x:data' type='submit'>
      <field var='FORM_TYPE' type='hidden'><value>
http://jabber.org/protocol/pubsub#node_config</value></field>
      <field var='pubsub#notify_retract'><value>0</value></field>
      <field var='pubsub#persist_items'><value>0</value></field>
      <field var='pubsub#publish_model'><value>subscribers</value></field>
      <field var='pubsub#access_model'><value>whitelist</value></field>
      <field
var='pubsub#send_last_published_item'><value>never</value></field>
</x></configure></pubsub></iq>

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9368' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='uuid1.105' jid='crea...@localhost/reprev'/>
</pubsub></iq>


4. Creator revs the collection whitelist, notifies collection members of the
whitelist change, and invites Contributor to join the collection:

<!-- whitelist update not yet implemented -->

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9370' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='uuid1.105' jid='crea...@localhost/reprev'><item>
      <user xmlns='reprev_ns' uid="contribu...@localhost" added="pending">
        contribu...@localhost
</user></item></publish></pubsub></iq>

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9369' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='contributor' jid='crea...@localhost/reprev'><item>
      <invite xmlns='reprev_ns' collection="uuid1.105">
        <from uid="crea...@localhost">Liam</from>
        <date>2010-01-19T20:45:26Z</date>
        <name>Cornucopia</name>
        <blurb>A non-descript invitation</blurb>
</invite></item></publish></pubsub></iq>


5. Contributor subscribes to the collection, and notifies Creator:

<iq from='contribu...@localhost/reprev' to='pubsub.localhost'
    type='set' id='8778' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='uuid1.105' jid='contribu...@localhost/reprev'/>
</pubsub></iq>

<iq from='contribu...@localhost/reprev' to='pubsub.localhost'
    type='set' id='8779' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='creator' jid='contribu...@localhost/reprev'><item>
      <join xmlns='reprev_ns' collection="uuid1.105"
uid="contribu...@localhost"/>
</item></publish></pubsub></iq>


6. Creator replicates collection to Contributor, first meta/data and then
revision history:

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9375' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='contributor' jid='crea...@localhost/reprev'><item>
      <replica xmlns='reprev_ns' collection='uuid1.105'>
        <!-- app-defined data -->
</replica></item></publish></pubsub></iq>

<iq from='crea...@localhost/reprev' to='pubsub.localhost'
    type='set' id='9376' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='contributor' jid='crea...@localhost/reprev'><item>
      <revision xmlns='reprev_ns' collection="uuid1.105">
        <revlist touch="2010-01-19T20:52:34Z" oid="uuid1.118">
          <object oid="uuid1.115" op="+" touch="2010-01-20T00:29:26Z"
diff="uuid1.120">
            <object oid="uuid1.116" op="+" touch="2010-01-20T00:29:26Z"
diff="uuid1.121"/></object></revlist>
        <diff orig="uuid1.115" oid="uuid1.120" type="not-implemented">
          <!-- app-defined content --></diff>
        <diff orig="uuid1.116" oid="uuid1.121" type="not-implemented">
          <!-- app-defined content --></diff>
</revision></item></publish></pubsub></iq>


7. Contributor makes a revision to collection:

<iq from='contribu...@localhost/reprev' to='pubsub.localhost'
    type='set' id='8784' xmlns='jabber:client'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='uuid1.105' jid='contribu...@localhost/reprev'><item
id='uuid2.106'>
      <revision xmlns='reprev_ns' collection="uuid1.105">
        <revlist touch="2010-01-19T21:00:36Z" oid="uuid2.106">
          <object oid="uuid1.116" op="!" touch="2010-01-20T00:29:26Z"
diff="uuid2.107"/></revlist>
        <diff orig="uuid1.116" oid="uuid2.107" type="not-implemented">
          <!-- app-defined content --></diff>
</revision></item></publish></pubsub></iq>


8. Contributor resigns from collection:

<!-- not yet implemented -->



On Mon, Jan 18, 2010 at 1:35 PM, Liam <pub...@networkimprov.net> wrote:

> I'm building an app which replicates collections of data objects among
> groups of contributors/subscribers.
>
> I use XMPP for transport & store-forward, and I've built a simple
> replication & revision system on top of PubSub.
>
> I'm considering open sourcing this code and documenting the protocol.
> (Source is javascript requiring Strophe.) Creating a separate package for
> this would entail some work, so I'd like to gauge potential interest...
>
> My replication & revision system does the following:
>
> Establishes pubsub nodes for shared collections
> Reliably transmits (reliable requires IQ Notifications):
>   - invitations to join a collection
>   - invitation acceptances
>   - collection copies to new members
>   - resignations from a collection
>   - revisions to a collection, containing:
>     a) list of revised objects
>     b) diffs for added/modified objects
>       format is app-specific; common diff types may be specified
>
> Obviously, it's very lightweight -- 5 message types (so far). It's not
> focused on real-time apps per se, but could be applied thereto.
>
> Also, I'd love pointers to other forums where folks could be interested...
>
> Liam
>
>

Reply via email to