git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@3141 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2009-05-14 20:07:07 +00:00
parent 9717d19509
commit 56922e5e95
1 changed files with 24 additions and 15 deletions

View File

@ -23,6 +23,12 @@
<shortname>N/A</shortname>
&stpeter;
&dcridland;
<revision>
<version>0.12</version>
<date>2009-05-14</date>
<initials>psa</initials>
<remark><p>Moved information about sending pushes to non-normative implementation guidelines; modified examples to reduce confusion.</p></remark>
</revision>
<revision>
<version>0.11</version>
<date>2009-04-30</date>
@ -124,7 +130,7 @@
<p>If a client supports roster versioning, it MUST include the 'ver' element in its request for the roster, where the 'ver' attribute is set to the version ID associated with its last cache of the roster.</p>
<example caption="Roster get with version ID"><![CDATA[
C: <iq from='romeo@montague.lit/home' id='r1h3vzp7' to='romeo@montague.lit' type='get'>
<query xmlns='jabber:iq:roster' ver='qAxdnWNcA+lYf7CoN5wpBsvVVno='/>
<query xmlns='jabber:iq:roster' ver='ver14'/>
</iq>
]]></example>
<p>If the client has not yet cached the roster or the cache is lost or corrupted, but the client wishes to bootstrap the use of roster versioning, it MUST set the 'ver' attribute to the empty string (i.e., <strong>ver=""</strong>).</p>
@ -138,22 +144,22 @@ S: <iq from='romeo@montague.lit' id='r1h3vzp7' to='romeo@montague.lit/home' type
<p>Note: This empty IQ-result is different from an empty &QUERY;, thus disambiguating this usage from an empty roster.</p>
<p>If the roster has not been modified since the version ID enumerated by the client, the server will simply not send any roster pushes to the client (until and unless some relevant event triggers a roster push during the lifetime of the client's session).</p>
<p>If the roster has been modified since the version ID enumerated by the client, the server MUST then send one roster push to the client for each roster item that has been modified since the version ID enumerated by the client. (We call a roster push that is sent for purposes of roster version synchronization an "interim roster push".)</p>
<p class='def'><strong>Definition:</strong> A <strong>"roster modification"</strong> is any modification to the roster data that would result in a roster push to a connected client. Therefore internal states related to roster processing within the server that would not result in a roster push to a connected client do not necessitate a change to the version. If a series of roster modifications result in a roster item that does not differ from the version cached by the client (e.g., a modification to the item's 'name' attribute and then a modification back to the original value), the server SHOULD NOT consider the item to have been modified for purposes of roster versioning and therefore SHOULD NOT push the item to the client in an interim roster push.</p>
<p class='def'><strong>Definition:</strong> A <strong>"roster modification"</strong> is any modification to the roster data that would result in a roster push to a connected client. Therefore internal states related to roster processing within the server that would not result in a roster push to a connected client do not necessitate a change to the version.</p>
<example caption="Roster pushes"><![CDATA[
S: <iq from='romeo@montague.lit' id='ah382g67' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='qAxdnWNcA+lYf7CoN5wpBsvVVno='>
<query xmlns='jabber:iq:roster' ver='ver34'>
<item jid='tybalt@shakespeare.lit' subscription='remove'/>
</query>
</iq>
S: <iq from='romeo@montague.lit' id='b2gs90j5' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='18sl3M/tdcyd1mwtn1hKmKOnacE='>
<query xmlns='jabber:iq:roster' ver='ver42'>
<item jid='bill@shakespeare.lit' subscription='both'/>
</query>
</iq>
S: <iq from='romeo@montague.lit' id='c73gs419' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='kkmqpuunFM5obGuZLN9ZgyKEVSs='>
<query xmlns='jabber:iq:roster' ver='ver72'>
<item jid='nurse@shakespeare.lit' name='Nurse' subscription='to'>
<group>Servants</group>
</item>
@ -161,7 +167,7 @@ S: <iq from='romeo@montague.lit' id='c73gs419' to='romeo@montague.lit/home' type
</iq>
S: <iq from='romeo@montague.lit' id='dh361f35' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='/gAR2erxkF5xLkRGaHJziC7B3LE='>
<query xmlns='jabber:iq:roster' ver='ver96'>
<item jid='juliet@shakespeare.lit' name='Juliet' subscription='both'>
<group>VIPs</group>
</item>
@ -170,9 +176,9 @@ S: <iq from='romeo@montague.lit' id='dh361f35' to='romeo@montague.lit/home' type
]]></example>
<p>These "interim roster pushes" can be understood as follows:</p>
<ol>
<li>Imagine that the client had an active presence session for the entire time between its cached roster version (say, "qAxdnWNcA+lYf7CoN5wpBsvVVno=") and the new roster version (say, "/gAR2erxkF5xLkRGaHJziC7B3LE=").</li>
<li>Imagine that the client had an active presence session for the entire time between its cached roster version (say, "ver14") and the new roster version (say, "ver96").</li>
<li>During that time, the client might have received roster pushes related to various roster versions. However, some of those roster pushes might have contained intermediate updates to the same roster item (e.g., modifications to the subscription state for bill@shakespeare.lit from "none" to "to" and from "to" to "both").</li>
<li>The interim roster pushes would not include all of the intermediate steps, only the final result of all modifications applied to each item while the client was in fact offline (say, "qAxdnWNcA+lYf7CoN5wpBsvVVno=", "18sl3M/tdcyd1mwtn1hKmKOnacE=", "kkmqpuunFM5obGuZLN9ZgyKEVSs=", and "/gAR2erxkF5xLkRGaHJziC7B3LE=").</li>
<li>The interim roster pushes would not include all of the intermediate steps, only the final result of all modifications applied to each item while the client was in fact offline (say, "ver34", "ver42", "ver72", and "ver96").</li>
</ol>
<p>The client MUST handle an "interim roster push" in the same way it handles any roster push (indeed, from the client's perspective it cannot tell the difference between an "interim" roster push and a "live" roster push). If the client's session ends before it receives all of the interim roster pushes, when requesting the roster after reconnection it SHOULD request the version associated with the last roster <em>push</em> it received during the session that was disconnected, not the version associated with the roster <em>result</em> it received at the start of the session that was disconnected.</p>
<p>When roster versioning is enabled, the server MUST include the updated roster version with each roster push. Roster pushes MUST occur in order of modification and the version contained in a roster push MUST be unique.</p>
@ -183,19 +189,19 @@ S: <iq from='romeo@montague.lit' id='dh361f35' to='romeo@montague.lit/home' type
<p>This section provides a detailed scenario that illustrates the use of roster versioning. In this example the client gets disconnected before the server has had a chance to send all of its roster pushes, but this is immaterial to the synchronization process.</p>
<example caption="The roster synchronization process"><![CDATA[
C: <iq from='romeo@montague.lit/home' id='r1h3vzp7' to='romeo@montague.lit' type='get'>
<query xmlns='jabber:iq:roster' ver='qAxdnWNcA+lYf7CoN5wpBsvVVno='/>
<query xmlns='jabber:iq:roster' ver='ver14'/>
</iq>
S: <iq from='romeo@montague.lit' id='r1h3vzp7' to='romeo@montague.lit/home' type='result'/>
S: <iq from='romeo@montague.lit' id='ah382g67' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='qAxdnWNcA+lYf7CoN5wpBsvVVno='>
<query xmlns='jabber:iq:roster' ver='ver34'>
<item jid='tybalt@shakespeare.lit' subscription='remove'/>
</query>
</iq>
S: <iq from='romeo@montague.lit' id='b2gs90j5' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='18sl3M/tdcyd1mwtn1hKmKOnacE='>
<query xmlns='jabber:iq:roster' ver='ver42'>
<item jid='bill@shakespeare.lit' subscription='both'/>
</query>
</iq>
@ -205,13 +211,13 @@ S: </stream:stream>
[ reconnection ]
C: <iq from='romeo@montague.lit/home' id='r2xa7gf9' to='romeo@montague.lit' type='get'>
<query xmlns='jabber:iq:roster' ver='18sl3M/tdcyd1mwtn1hKmKOnacE='/>
<query xmlns='jabber:iq:roster' ver='ver34'/>
</iq>
S: <iq from='romeo@montague.lit' id='r2xa7gf9' to='romeo@montague.lit/home' type='result'/>
S: <iq from='romeo@montague.lit' id='c73gs419' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='kkmqpuunFM5obGuZLN9ZgyKEVSs='>
<query xmlns='jabber:iq:roster' ver='ver72'>
<item jid='nurse@shakespeare.lit' name='Nurse' subscription='to'>
<group>Servants</group>
</item>
@ -219,7 +225,7 @@ S: <iq from='romeo@montague.lit' id='c73gs419' to='romeo@montague.lit/home' type
</iq>
S: <iq from='romeo@montague.lit' id='dh361f35' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='/gAR2erxkF5xLkRGaHJziC7B3LE='>
<query xmlns='jabber:iq:roster' ver='ver96'>
<item jid='juliet@shakespeare.lit' name='Juliet' subscription='both'>
<group>VIPs</group>
</item>
@ -260,6 +266,9 @@ S: <iq from='romeo@montague.lit' id='dh361f35' to='romeo@montague.lit/home' type
<p>Implementors could combine this strategy with the previous one, detecting a sequence of modifications yielding the same roster as the client has cached already, by constructing a ver attribute containing both a hash and sequence value. This might provide some resilience in the case of data loss.</p>
<p>Implementors are advised that a pure timestamp is not suitable for this approach, since under some circumstances system clocks can go backwards (e.g., because of an adjustment based on an update triggered by use of the Network Time Protocol as described in &rfc0958;).</p>
</section2>
<section2 topic='Sending Pushes' anchor='impl-push'>
<p>There are two primary approaches to server-side generation of the 'ver' attribute: complete roster hashes and strictly increasing sequence numbers. Whether the server will send roster pushes varies depending on the approach taken. For instance, if a series of roster modifications result in a roster item that does not differ from the version cached by the client (e.g., a modification to the item's 'name' attribute and then a modification back to the original value), then a server that implements the "complete roster hashes" approach would consider the item to have been modified for purposes of roster versioning and therefore would push the item to the client in an interim roster push; however, a server that implements the "strictly increasing sequence numbers" approach would send a roster push in this situtation.</p>
</section2>
<section2 topic='Client Implementation Guidelines' anchor='impl-client'>
<p>Client implementors are reminded that the value of the 'ver' attribute is entirely opaque, and they should behave identically with each strategy described above by simply conforming to the specification. The only storage requirement for this specification is the last seen 'ver' attribute.</p>
</section2>
@ -321,7 +330,7 @@ S: <iq from='romeo@montague.lit' id='dh361f35' to='romeo@montague.lit/home' type
</section1>
<section1 topic='Acknowledgements' anchor='ack'>
<p>Thanks to Dave Cridland, Richard Dobson, Leonid Evdokimov, Fabio Forno, Alexander Gnauck, Juha Hartikainen, Joe Hildebrand, Justin Karneges, Sachin Khandelwal, Curtis King, Jonas Lindberg, Pedro Melo, Matthew Wild, and Jiří Zárevúcký for their comments.</p>
<p>Thanks to Dave Cridland, Richard Dobson, Leonid Evdokimov, Fabio Forno, Alexander Gnauck, Juha Hartikainen, Joe Hildebrand, Waqas Hussain, Justin Karneges, Sachin Khandelwal, Curtis King, Jonas Lindberg, Pedro Melo, Matthew Wild, Jiří Zárevúcký, and Florian Zeitz for their comments.</p>
</section1>
</xep>