The protocol sequence below is derived from an exchange between instances of my app. Typos could have crept in during editing!<br><br>There are features missing... splitting &lt;revision/&gt; messages to fit the max payload size for the node, and types for diff formats.<br>
<br>Feedback welcome!<br><br><br>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.)<br><br>&lt;iq from=&#39;creator@localhost/<br>
reprev&#39; to=&#39;pubsub.localhost&#39;<br>    type=&#39;set&#39; id=&#39;9365&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>
    &lt;create node=&#39;creator&#39;/&gt;<br>    &lt;configure&gt;&lt;x xmlns=&#39;jabber:x:data&#39; type=&#39;submit&#39;&gt;<br>      &lt;field var=&#39;FORM_TYPE&#39; type=&#39;hidden&#39;&gt;&lt;value&gt;<a href="http://jabber.org/protocol/pubsub#node_config">http://jabber.org/protocol/pubsub#node_config</a>&lt;/value&gt;&lt;/field&gt;<br>
      &lt;field var=&#39;pubsub#notify_retract&#39;&gt;&lt;value&gt;0&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#persist_items&#39;&gt;&lt;value&gt;0&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#publish_model&#39;&gt;&lt;value&gt;open&lt;/value&gt;&lt;/field&gt;<br>
      &lt;field var=&#39;pubsub#access_model&#39;&gt;&lt;value&gt;whitelist&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#send_last_published_item&#39;&gt;&lt;value&gt;never&lt;/value&gt;&lt;/field&gt;<br>
&lt;/x&gt;&lt;/configure&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br><br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>    type=&#39;set&#39; id=&#39;9366&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>
    &lt;subscribe node=&#39;creator&#39; jid=&#39;creator@localhost/reprev&#39;/&gt;<br>&lt;/pubsub&gt;&lt;/iq&gt;<br><br><br>2. Contributor does the same:<br><br>&lt;iq from=&#39;contributor@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>
    type=&#39;set&#39; id=&#39;8776&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;create node=&#39;contributor&#39;/&gt;<br>
    &lt;configure&gt;&lt;x xmlns=&#39;jabber:x:data&#39; type=&#39;submit&#39;&gt;<br>      &lt;field var=&#39;FORM_TYPE&#39; type=&#39;hidden&#39;&gt;&lt;value&gt;<a href="http://jabber.org/protocol/pubsub#node_config">http://jabber.org/protocol/pubsub#node_config</a>&lt;/value&gt;&lt;/field&gt;<br>
      &lt;field var=&#39;pubsub#notify_retract&#39;&gt;&lt;value&gt;0&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#persist_items&#39;&gt;&lt;value&gt;0&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#publish_model&#39;&gt;&lt;value&gt;open&lt;/value&gt;&lt;/field&gt;<br>
      &lt;field var=&#39;pubsub#access_model&#39;&gt;&lt;value&gt;whitelist&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#send_last_published_item&#39;&gt;&lt;value&gt;never&lt;/value&gt;&lt;/field&gt;<br>
&lt;/x&gt;&lt;/configure&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br><br>&lt;iq from=&#39;contributor@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>    type=&#39;set&#39; id=&#39;8777&#39; xmlns=&#39;jabber:client&#39;&gt;<br>
  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;subscribe node=&#39;contributor&#39; jid=&#39;contributor@localhost/reprev&#39;/&gt;<br>&lt;/pubsub&gt;&lt;/iq&gt;<br>
<br><br>3. Creator makes a pubsub node for a shared collection, and subscribes:<br><br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>    type=&#39;set&#39; id=&#39;9367&#39; xmlns=&#39;jabber:client&#39;&gt;<br>
  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;create node=&#39;uuid1.105&#39;/&gt;<br>    &lt;configure&gt;&lt;x xmlns=&#39;jabber:x:data&#39; type=&#39;submit&#39;&gt;<br>
      &lt;field var=&#39;FORM_TYPE&#39; type=&#39;hidden&#39;&gt;&lt;value&gt;<a href="http://jabber.org/protocol/pubsub#node_config">http://jabber.org/protocol/pubsub#node_config</a>&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#notify_retract&#39;&gt;&lt;value&gt;0&lt;/value&gt;&lt;/field&gt;<br>
      &lt;field var=&#39;pubsub#persist_items&#39;&gt;&lt;value&gt;0&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#publish_model&#39;&gt;&lt;value&gt;subscribers&lt;/value&gt;&lt;/field&gt;<br>      &lt;field var=&#39;pubsub#access_model&#39;&gt;&lt;value&gt;whitelist&lt;/value&gt;&lt;/field&gt;<br>
      &lt;field var=&#39;pubsub#send_last_published_item&#39;&gt;&lt;value&gt;never&lt;/value&gt;&lt;/field&gt;<br>&lt;/x&gt;&lt;/configure&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br><br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>
    type=&#39;set&#39; id=&#39;9368&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;subscribe node=&#39;uuid1.105&#39; jid=&#39;creator@localhost/reprev&#39;/&gt;<br>
&lt;/pubsub&gt;&lt;/iq&gt;<br><br><br>4. Creator revs the collection whitelist, notifies collection members of the whitelist change, and invites Contributor to join the collection:<br><br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>
    type=&#39;set&#39; id=&#39;9372&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;affiliations node=&#39;uuid1.105&#39;&gt;<br>
      &lt;affiliation jid=&#39;contributor@localhost&#39; affiliation=&#39;publisher&#39;/&gt;<br>&lt;/affiliations&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br><br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>
    type=&#39;set&#39; id=&#39;9370&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;publish node=&#39;uuid1.105&#39; jid=&#39;creator@localhost/reprev&#39;&gt;&lt;item&gt;<br>
      &lt;member xmlns=&#39;reprev_ns&#39; uid=&quot;contributor@localhost&quot; added=&quot;pending&quot;&gt;<br>        contributor@localhost<br>&lt;/member&gt;&lt;/item&gt;&lt;/publish&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br>
<br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>    type=&#39;set&#39; id=&#39;9369&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>
    &lt;publish node=&#39;contributor&#39; jid=&#39;creator@localhost/reprev&#39;&gt;&lt;item&gt;<br>      &lt;invite xmlns=&#39;reprev_ns&#39; collection=&quot;uuid1.105&quot;&gt;<br>        &lt;from uid=&quot;creator@localhost&quot;&gt;Liam&lt;/from&gt;<br>
        &lt;date&gt;2010-01-19T20:45:26Z&lt;/date&gt;<br>        &lt;name&gt;Cornucopia&lt;/name&gt;<br>        &lt;blurb&gt;A non-descript invitation&lt;/blurb&gt;<br>&lt;/invite&gt;&lt;/item&gt;&lt;/publish&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br>
<br><br>5. Contributor subscribes to the collection, and notifies Creator:<br><br>&lt;iq from=&#39;contributor@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>    type=&#39;set&#39; id=&#39;8778&#39; xmlns=&#39;jabber:client&#39;&gt;<br>
  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;subscribe node=&#39;uuid1.105&#39; jid=&#39;contributor@localhost/reprev&#39;/&gt;<br>&lt;/pubsub&gt;&lt;/iq&gt;<br>
<br>&lt;iq from=&#39;contributor@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>    type=&#39;set&#39; id=&#39;8779&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>
    &lt;publish node=&#39;creator&#39; jid=&#39;contributor@localhost/reprev&#39;&gt;&lt;item&gt;<br>      &lt;join xmlns=&#39;reprev_ns&#39; collection=&quot;uuid1.105&quot; uid=&quot;contributor@localhost&quot;/&gt;<br>
&lt;/item&gt;&lt;/publish&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br><br><br>6. Creator replicates collection to Contributor, first meta/data and then revision history:<br><br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>
    type=&#39;set&#39; id=&#39;9375&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;publish node=&#39;contributor&#39; jid=&#39;creator@localhost/reprev&#39;&gt;&lt;item&gt;<br>
      &lt;replica xmlns=&#39;reprev_ns&#39; collection=&#39;uuid1.105&#39;&gt;<br>        &lt;!-- app-defined data --&gt;<br>&lt;/replica&gt;&lt;/item&gt;&lt;/publish&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br><br>&lt;iq from=&#39;creator@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>
    type=&#39;set&#39; id=&#39;9376&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;publish node=&#39;contributor&#39; jid=&#39;creator@localhost/reprev&#39;&gt;&lt;item&gt;<br>
      &lt;revision xmlns=&#39;reprev_ns&#39; collection=&quot;uuid1.105&quot;&gt;<br>        &lt;revlist touch=&quot;2010-01-19T20:52:34Z&quot; oid=&quot;uuid1.118&quot;&gt;<br>          &lt;object oid=&quot;uuid1.115&quot; op=&quot;+&quot; touch=&quot;2010-01-20T00:29:26Z&quot; diff=&quot;uuid1.120&quot;&gt;<br>
            &lt;object oid=&quot;uuid1.116&quot; op=&quot;+&quot; touch=&quot;2010-01-20T00:29:26Z&quot; diff=&quot;uuid1.121&quot;/&gt;&lt;/object&gt;&lt;/revlist&gt;<br>        &lt;diff orig=&quot;uuid1.115&quot; oid=&quot;uuid1.120&quot; type=&quot;not-implemented&quot;&gt;<br>
          &lt;!-- app-defined content --&gt;&lt;/diff&gt;<br>        &lt;diff orig=&quot;uuid1.116&quot; oid=&quot;uuid1.121&quot; type=&quot;not-implemented&quot;&gt;<br>          &lt;!-- app-defined content --&gt;&lt;/diff&gt;<br>
&lt;/revision&gt;&lt;/item&gt;&lt;/publish&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br><br><br>7. Contributor makes a revision to collection:<br><br>&lt;iq from=&#39;contributor@localhost/reprev&#39; to=&#39;pubsub.localhost&#39;<br>
    type=&#39;set&#39; id=&#39;8784&#39; xmlns=&#39;jabber:client&#39;&gt;<br>  &lt;pubsub xmlns=&#39;<a href="http://jabber.org/protocol/pubsub">http://jabber.org/protocol/pubsub</a>&#39;&gt;<br>    &lt;publish node=&#39;uuid1.105&#39; jid=&#39;contributor@localhost/reprev&#39;&gt;&lt;item id=&#39;uuid2.106&#39;&gt;<br>
      &lt;revision xmlns=&#39;reprev_ns&#39; collection=&quot;uuid1.105&quot;&gt;<br>        &lt;revlist touch=&quot;2010-01-19T21:00:36Z&quot; oid=&quot;uuid2.106&quot;&gt;<br>          &lt;object oid=&quot;uuid1.116&quot; op=&quot;!&quot; touch=&quot;2010-01-20T00:29:26Z&quot; diff=&quot;uuid2.107&quot;/&gt;&lt;/revlist&gt;<br>
        &lt;diff orig=&quot;uuid1.116&quot; oid=&quot;uuid2.107&quot; type=&quot;not-implemented&quot;&gt;<br>          &lt;!-- app-defined content --&gt;&lt;/diff&gt;<br>&lt;/revision&gt;&lt;/item&gt;&lt;/publish&gt;&lt;/pubsub&gt;&lt;/iq&gt;<br>
<br><br>8. Contributor resigns from collection:<br><br>&lt;!-- not yet implemented --&gt;<br><br><br><div class="gmail_quote">On Wed, Jan 20, 2010 at 3:44 PM, Liam <span dir="ltr">&lt;<a href="mailto:pubsub@networkimprov.net">pubsub@networkimprov.net</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">I&#39;m building an app which replicates collections of data objects among groups of contributors/subscribers.<br>
</div><div class="gmail_quote"><div class="im"><br>I use XMPP for transport &amp; store-forward, and I&#39;ve built a simple replication &amp; revision system on top of PubSub.<br>



<br>I&#39;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&#39;d like to gauge potential interest...<br>










<br>My replication &amp; revision system does the following:<br><br>Establishes pubsub nodes for shared collections<br>Reliably transmits (reliable requires IQ Notifications):<br>  - invitations to join a
collection<br>  - invitation acceptances<br></div>  - collection replicas to new members<br><div class="im">  - resignations from a collection<br>  - revisions to a
collection, containing:<br>    a) list of revised objects<br>    b) diffs for added/modified objects<br>       format is app-specific; common diff types may be specified<br><br></div>Obviously, it&#39;s very lightweight. It&#39;s not focused on real-time apps per se, but could be applied thereto.<br>
<div class="im">



<br>Also, I&#39;d love pointers to other forums where folks could be interested...<br>




<br>Liam<br><br></div>PS: protocol specifics to follow...<br><br></div>
</blockquote></div><br>