mirror of
https://github.com/moparisthebest/xeps
synced 2024-12-21 23:28:51 -05:00
60c37405ae
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@48 4b5297f7-1745-476d-ba37-a9c6900126ab
768 lines
43 KiB
XML
768 lines
43 KiB
XML
<?xml version='1.0' encoding='UTF-8'?>
|
|
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
|
<!ENTITY % ents SYSTEM 'xep.ent'>
|
|
%ents;
|
|
]>
|
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
|
<xep>
|
|
<header>
|
|
<title>Personal Eventing via Pubsub</title>
|
|
<abstract>This document specifies XMPP semantics for using the publish-subscribe protocol to broadcast state change events associated with an instant messaging and presence account.</abstract>
|
|
&LEGALNOTICE;
|
|
<number>0163</number>
|
|
<status>Draft</status>
|
|
<type>Standards Track</type>
|
|
<jig>Standards JIG</jig>
|
|
<approver>Council</approver>
|
|
<dependencies>
|
|
<spec>XMPP Core</spec>
|
|
<spec>XMPP IM</spec>
|
|
<spec>XEP-0030</spec>
|
|
<spec>XEP-0060</spec>
|
|
<spec>XEP-0115</spec>
|
|
</dependencies>
|
|
<supersedes/>
|
|
<supersededby/>
|
|
<shortname>pep</shortname>
|
|
&stpeter;
|
|
<author>
|
|
<firstname>Kevin</firstname>
|
|
<surname>Smith</surname>
|
|
<email>kevin@kismith.co.uk</email>
|
|
<jid>kevdadrum@jabber.ex.ac.uk</jid>
|
|
</author>
|
|
<revision>
|
|
<version>1.0</version>
|
|
<date>2006-09-20</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Per a vote of the Jabber Council, advanced status to Draft.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.15</version>
|
|
<date>2006-08-30</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Added the deliver_notifications and send_last_published_item configuration options to the recommended defaults.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.14</version>
|
|
<date>2006-08-02</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Changed various recommended defaults from SHOULD to MUST; corrected several errors in the text and examples.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.13</version>
|
|
<date>2006-08-01</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Recommended node creation with default configuration on initial publish; corrected several errors and clarified several points in the text.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.12</version>
|
|
<date>2006-08-01</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Simplified the subscription process using XMPP presence and entity capabilities.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.11</version>
|
|
<date>2006-07-20</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Clarified rules regarding number of notifications and when to generate notifications; corrected several errors in the text and examples.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.10</version>
|
|
<date>2006-07-07</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Updated to reflect version 1.8 of XEP-0060.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.9</version>
|
|
<date>2006-06-15</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Updated to reflect use of data forms in XEP-0060.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.8</version>
|
|
<date>2006-04-10</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Clarified terminology and defaults.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.7</version>
|
|
<date>2006-04-10</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Specified that notifications are to be sent from bare JID, not full JID.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.6</version>
|
|
<date>2006-04-10</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Updated to reflect pubsub changes; clarified business rules for generation of notifications and cancellation of subscriptions.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.5</version>
|
|
<date>2006-03-09</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Modified roster groups example to use jabber:x:data; added note about advertising client support for PEP.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.4</version>
|
|
<date>2006-02-02</date>
|
|
<initials>psa/ks</initials>
|
|
<remark><p>Specified rules for generation of notifications, including use of presence in determining address of intended recipient for notifications and sending of last published item on receipt of presence information; changed name to Personal Eventing Protocol; specified service discovery identity of pubsub/pep; removed section on service types; added Kevin Smith as co-author.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.3</version>
|
|
<date>2006-01-30</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Specified that a service may enforce additional privacy and security policies; specified that an account owner must always be allowed to subscribe and to retrieve items; specified that an implementation should enforce access modifications resulting from roster state changes.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.2</version>
|
|
<date>2006-01-11</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Updated to reflect proposed XEP-0060 modifications.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.1</version>
|
|
<date>2005-11-02</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Initial version.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.0.2</version>
|
|
<date>2005-10-25</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Added more details and examples.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.0.1</version>
|
|
<date>2005-10-24</date>
|
|
<initials>psa</initials>
|
|
<remark><p>First draft.</p></remark>
|
|
</revision>
|
|
</header>
|
|
|
|
<section1 topic='Introduction' anchor='intro'>
|
|
<p>The XMPP &xep0060; extension ("pubsub") can be used to broadcast state change events associated with a Jabber/XMPP account or user, such as those described in &xep0080;, &xep0107;, &xep0108;, and &xep0118;. <note>Currently, many "extended presence" formats are sent using the &PRESENCE; stanza type; however, this overloads presence, results in unnecessary presence traffic, and does not provide fine-grained control over access. The use of publish-subscribe rather than presence is therefore preferable.</note> However, the full, generic pubsub protocol is often thought of as complicated and therefore has not been widely implemented. To make publish-subscribe functionality more accessible (especially to instant messaging and presence applications that conform to &xmppim;), this document defines simplified protocol semantics that can be followed by instant messaging client and server developers, hopefully resulting in the deployment of personal eventing services across the Jabber/XMPP network.</p>
|
|
<p><em>Note: This document does not show error flows related to the various publish-subscribe use cases referenced herein, since they are exhaustively defined in <cite>XEP-0060</cite>. The reader is referred to <cite>XEP-0060</cite> for all relevant protocol details related to the XMPP publish-subscribe extension.</em></p>
|
|
</section1>
|
|
|
|
<section1 topic='Concepts and Approach' anchor='approach'>
|
|
<p>Personal eventing via pubsub ("PEP") is based on six principles:</p>
|
|
<ol start='1'>
|
|
<li>Every account a pubsub service.</li>
|
|
<li>One publisher per node.</li>
|
|
<li>One node per namespace.</li>
|
|
<li>Use presence.</li>
|
|
<li>Notifications are filtered based on expressed interests.</li>
|
|
<li>Smart defaults.</li>
|
|
</ol>
|
|
<p>These principles are described more fully below.</p>
|
|
<section2 topic='Every Account a Pubsub Service' anchor='approach-everyjid'>
|
|
<p>When a user creates an account (or has an account provisioned) at a Jabber/XMPP server that supports PEP, the server associates a virtual pubsub service with the account. This greatly simplifies the task of discovering the account owner's personal pubsub nodes, since the root pubsub node simply is the account owner's bare JID (&BAREJID;). This assumption also simplifies publishing and subscribing.</p>
|
|
</section2>
|
|
<section2 topic='One Publisher Per Node' anchor='approach-publisher'>
|
|
<p>There is no need for multiple publishers to a PEP service, since by definition the service generates information associated with only one entity. The owner-publisher for every node is the bare JID of the account owner.</p>
|
|
</section2>
|
|
<section2 topic='One Node Per Namespace' anchor='approach-onenode'>
|
|
<p>There is only one publish-subscribe node associated with any given payload type (XML namespace) for the account owner (e.g., there is one pubsub node for geolocation events, one node for tune events, and one node for mood events). This simplifies node creation, discovery, publishing, and subscribing.</p>
|
|
</section2>
|
|
<section2 topic='Use Presence' anchor='approach-presence'>
|
|
<p>Although generic publish-subscribe services do not necessarily have access to presence information about subscribers, PEP services are integrated with presence in the following ways:</p>
|
|
<ul>
|
|
<li>Each messaging and presence account simply <em>is</em> a virtual publish-subscribe service.</li>
|
|
<li>The default access model is "presence".</li>
|
|
<li>A contact's subscription to an account owner's personal eventing data is normally handled via the existence of an XMPP presence subscription.</li>
|
|
<li>Services take account of subscriber presence in the generation of notifications. <note>This works only if the subscription state is "both" (see <cite>RFC 3921</cite>).</note></li>
|
|
</ul>
|
|
<p>These uses of presence simplify the task of developing compliant clients (cf. &xep0134;).</p>
|
|
</section2>
|
|
<section2 topic='Filtered Notifications' anchor='approach-filter'>
|
|
<p>By default, the existence of an XMPP presence subscription is used to establish a PEP subscription to the account owner's personal eventing data. In order to filter which notifications are sent by the PEP service, the contact's client includes extended &xep0115; information in the presence notifications it sends to the account owner, and the PEP service sends only those notifications that match the contact's expressed notification preferences.</p>
|
|
</section2>
|
|
<section2 topic='Smart Defaults' anchor='approach-defaults'>
|
|
<p>Most pubsub configuration options and metadata are not needed for personal eventing. Instead, PEP services offer smart defaults to simplify node creation and management.</p>
|
|
</section2>
|
|
</section1>
|
|
|
|
<section1 topic='Scenario' anchor='scenario'>
|
|
<p>This document illustrates PEP through a series of examples that use the following scenario:</p>
|
|
<ol start='1'>
|
|
<li>
|
|
<p>An owner-publisher juliet@capulet.com who publishes the following information:</p>
|
|
<ol start='1'>
|
|
<li>Tune information that anyone may see (i.e., an access model of "open")</li>
|
|
<li>Activity information that only subscribers to her presence may see (i.e., an access model of "presence")</li>
|
|
<li>Geolocation information that only contacts in her "Friends" group may see (i.e., an access model of "roster" with a group of "Friends")</li>
|
|
<li>Bookmark information that only the account owner may see (i.e., an access model of "whitelist")</li>
|
|
</ol>
|
|
<p>Note: A PEP node with an access model of "whitelist" and no entities on the whitelist effectively results in a node that enables private data storage; for details, see the <link url='#privatedata'>Private Data Storage</link> section of this document.</p>
|
|
</li>
|
|
<li>
|
|
<p>Three users who have the following relationship to Juliet:</p>
|
|
<ol start='1'>
|
|
<li>benvolio@montague.net, who has no subscription to Juliet's presence</li>
|
|
<li>nurse@capulet.com, who has a bidirectional subscription to Juliet's presence and who is in the "Servants" group in Juliet's roster</li>
|
|
<li>romeo@montague.net, who has a bidirectional subscription to Juliet's presence and who is in the "Friends" group in Juliet's roster</li>
|
|
</ol>
|
|
</li>
|
|
</ol>
|
|
<p>The examples shown in the following sections walk through the protocol flows for node creation, discovery, publishing, and subscribing.</p>
|
|
</section1>
|
|
|
|
<section1 topic='Account Owner Service Discovery' anchor='owner-disco'>
|
|
<p>Naturally, before an account owner attempts to complete any PEP use cases, its client SHOULD determine whether the account owner's server supports PEP; to do so, it MUST send a &xep0030; information request to the server:</p>
|
|
<example caption='Account owner queries server regarding protocol support'><![CDATA[
|
|
<iq from='juliet@capulet.com/balcony'
|
|
to='capulet.com'
|
|
id='disco1'
|
|
type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'/>
|
|
</iq>
|
|
]]></example>
|
|
<p>If a server supports PEP, it MUST return an identity of "pubsub/pep" (as well as a list of the namespaces and other features it supports, including all supported <cite>XEP-0060</cite> features):</p>
|
|
<example caption='Server communicates protocol support'><![CDATA[
|
|
<iq from='capulet.com'
|
|
to='juliet@capulet.com/balcony'
|
|
id='disco1'
|
|
type='result'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'>
|
|
<identity category='server' type='im'/>
|
|
<identity category='pubsub' type='pep'/>
|
|
<feature var='http://jabber.org/protocol/pubsub#config-node'/>
|
|
<feature var='http://jabber.org/protocol/pubsub#create-and-configure'/>
|
|
<feature var='http://jabber.org/protocol/pubsub#create-nodes'/>
|
|
<feature var='http://jabber.org/protocol/pubsub#persistent-items'/>
|
|
<feature var='http://jabber.org/protocol/pubsub#publish'/>
|
|
<feature var='http://jabber.org/protocol/pubsub#retrieve-items'/>
|
|
<feature var='http://jabber.org/protocol/pubsub#subscribe'/>
|
|
...
|
|
</query>
|
|
</iq>
|
|
]]></example>
|
|
</section1>
|
|
|
|
<section1 topic='Account Owner Node Creation' anchor='owner-create'>
|
|
<p>When an account owner attempts to publish an item to a PEP node and that node does not already exist, the PEP service MUST automatically create the node with default configuration. <note>This similar to the room creation process in <cite>XEP-0045: Multi-User Chat</cite>.</note> However, if the account owner wishes to create a node with a configuration other than the default (e.g., a node with an access model of "open", "roster", or "whitelist"), the account owner MUST follow the node creation protocol specified in <cite>XEP-0060</cite>.</p>
|
|
<p>For example, Juliet would send the following stanzas in order to create the nodes mentioned above:</p>
|
|
<example caption='Account owner creates open node for tune data'><![CDATA[
|
|
<iq from='juliet@capulet.com/balcony' type='set' id='create-open'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<create node='http://jabber.org/protocol/tune'/>
|
|
<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#access_model'>
|
|
<option><value>open</value></option>
|
|
</field>
|
|
</x>
|
|
</configure>
|
|
</pubsub>
|
|
</iq>
|
|
|
|
<iq to='juliet@capulet.com/balcony' type='result' id='create-open'/>
|
|
]]></example>
|
|
<example caption='Account owner publishes initial item to presence node for activity data'><![CDATA[
|
|
<iq from='juliet@capulet.com/balcony' type='set' id='create-presence'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<publish node='http://jabber.org/protocol/activity'/>
|
|
<item>
|
|
<activity xmlns='http://jabber.org/protocol/activity'>
|
|
<relaxing>
|
|
<partying/>
|
|
</relaxing>
|
|
<text xml:lang='en'>My nurse's birthday!</text>
|
|
</activity>
|
|
</item>
|
|
</publish>
|
|
</pubsub>
|
|
</iq>
|
|
|
|
<iq to='juliet@capulet.com/balcony' type='result' id='create-presence'/>
|
|
]]></example>
|
|
<example caption='Account owner creates roster access node for geolocation data'><![CDATA[
|
|
<iq from='juliet@capulet.com/balcony' type='set' id='create-roster'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<create node='http://jabber.org/protocol/geoloc'/>
|
|
<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#access_model'>
|
|
<option><value>roster</value></option>
|
|
</field>
|
|
<field var='pubsub#roster_groups_allowed'>
|
|
<option><value>Friends</value></option>
|
|
</field>
|
|
</x>
|
|
</configure>
|
|
</pubsub>
|
|
</iq>
|
|
|
|
<iq to='juliet@capulet.com/balcony' type='result' id='create-roster'/>
|
|
]]></example>
|
|
<example caption='Account owner creates whitelist node for bookmark data'><![CDATA[
|
|
<iq from='juliet@capulet.com/balcony' type='set' id='create-whitelist'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<create node='storage:bookmarks'/>
|
|
<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#access_model'>
|
|
<option><value>whitelist</value></option>
|
|
</field>
|
|
</x>
|
|
</configure>
|
|
</pubsub>
|
|
</iq>
|
|
|
|
<iq to='juliet@capulet.com/balcony' type='result' id='create-whitelist'/>
|
|
]]></example>
|
|
</section1>
|
|
|
|
<section1 topic='Contact Service Discovery' anchor='contact-disco'>
|
|
<p>A contact MAY send service discovery requests to the account owner's bare JID (&BAREJID;). Although this is not necessary in order to subscribe to the account owner's personal eventing data (as explained in the following section), it is shown here to further illustrate the role of access models.</p>
|
|
<p>First, benvolio@montague.net sends a disco#info request to juliet@capulet.com:</p>
|
|
<example caption='Unaffiliated entity queries account owner regarding identity'><![CDATA[
|
|
<iq from='benvolio@montague.net/home'
|
|
to='juliet@capulet.com'
|
|
id='disco2'
|
|
type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'/>
|
|
</iq>
|
|
]]></example>
|
|
<p>If Juliet's server supports PEP (thereby making juliet@capulet.com a virtual pubsub service), it MUST return an identity of "pubsub/pep":</p>
|
|
<example caption='Server communicates protocol support'><![CDATA[
|
|
<iq from='juliet@capulet.com'
|
|
to='benvolio@montague.net/home'
|
|
id='disco2'
|
|
type='result'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'>
|
|
<identity category='pubsub' type='pep'/>
|
|
<identity category='account' type='registered'/>
|
|
...
|
|
</query>
|
|
</iq>
|
|
]]></example>
|
|
<p>Second, benvolio@montague.net sends a disco#items request to juliet@capulet.com:</p>
|
|
<example caption='Unaffiliated entity queries account owner regarding items'><![CDATA[
|
|
<iq from='benvolio@montague.net/home'
|
|
to='juliet@capulet.com'
|
|
id='disco3'
|
|
type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#items'/>
|
|
</iq>
|
|
]]></example>
|
|
<p>The account owner's server MUST check the access model for each of the account owner's PEP nodes and MUST return as service discovery items only those nodes to which the contact is allowed to subscribe or from which the contact is allowed to retrieve items without first subscribing.</p>
|
|
<p>Therefore, in this case, the server would return only the "http://jabber.org/protocol/tune" node (since it has an open access model and the contact does not have a presence subscription to the account owner's presence):</p>
|
|
<example caption='Server returns appropriate items'><![CDATA[
|
|
<iq from='juliet@capulet.com'
|
|
to='benvolio@montague.net/home'
|
|
id='disco3'
|
|
type='result'>
|
|
<query xmlns='http://jabber.org/protocol/disco#items'>
|
|
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/tune'/>
|
|
</query>
|
|
</iq>
|
|
]]></example>
|
|
<p>Next, nurse@capulet.com sends a disco#items request to juliet@capulet.com:</p>
|
|
<example caption='Contact with presence subscription queries account owner regarding items'><![CDATA[
|
|
<iq from='nurse@capulet.com/chamber'
|
|
to='juliet@capulet.com'
|
|
id='disco4'
|
|
type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#items'/>
|
|
</iq>
|
|
]]></example>
|
|
<p>However, in this case, the server would return the "http://jabber.org/protocol/tune" node (open access model) <em>and</em> the "http://jabber.org/protocol/activity" node (presence access model):</p>
|
|
<example caption='Server returns appropriate items'><![CDATA[
|
|
<iq from='juliet@capulet.com'
|
|
to='nurse@capulet.com/chamber'
|
|
id='disco4'
|
|
type='result'>
|
|
<query xmlns='http://jabber.org/protocol/disco#items'>
|
|
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/tune'/>
|
|
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/activity'/>
|
|
</query>
|
|
</iq>
|
|
]]></example>
|
|
<p>Finally, romeo@montague.net sends a disco#items request to juliet@capulet.com:</p>
|
|
<example caption='Contact with presence subscription and in privileged roster group queries account owner regarding items'><![CDATA[
|
|
<iq from='romeo@montague.net/orchard'
|
|
to='juliet@capulet.com'
|
|
id='disco5'
|
|
type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#items'/>
|
|
</iq>
|
|
]]></example>
|
|
<p>In this case, the server would return the "http://jabber.org/protocol/tune" node (open access model) <em>and</em> the "http://jabber.org/protocol/activity" node (presence access model) <em>and</em> the "http://jabber.org/protocol/geoloc" node (roster access model):</p>
|
|
<example caption='Server returns appropriate items'><![CDATA[
|
|
<iq from='juliet@capulet.com'
|
|
to='romeo@montague.net/orchard'
|
|
id='disco5'
|
|
type='result'>
|
|
<query xmlns='http://jabber.org/protocol/disco#items'>
|
|
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/tune'/>
|
|
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/activity'/>
|
|
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/geoloc'/>
|
|
</query>
|
|
</iq>
|
|
]]></example>
|
|
</section1>
|
|
|
|
<section1 topic='Contact Subscription' anchor='contact-subscribe'>
|
|
<p>If an entity is not subscribed to the account owner's presence, it MUST subscribe to a node using the protocol defined in <cite>XEP-0060</cite>. For instance, here is how benvolio@montague.net would subscribe Juliet's tune information:</p>
|
|
<example caption='Unaffiliated entity subscribes to an open node'><![CDATA[
|
|
<iq type='set'
|
|
from='benvolio@montague.net/home'
|
|
to='juliet@capulet.com'
|
|
id='sub1'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<subscribe node='http://jabber.org/protocol/tune' jid='benvolio@montague.net'/>
|
|
</pubsub>
|
|
</iq>
|
|
]]></example>
|
|
<p>However, when a contact is affiliated with the account owner through a presence subscription, PEP greatly simplifies the subscription process. This is done by associating the presence subscription with a pubsub subscription to the account owner's root collection node (i.e., bare JID), with a subscription_type of "items" and a subscription_depth of "all".</p>
|
|
<p>Consider the following presence subscription exchange:</p>
|
|
<example caption='Presence subscription handshake'><![CDATA[
|
|
<presence from='nurse@capulet.com' to='juliet@capulet.com' type='subscribe'/>
|
|
|
|
<presence from='juliet@capulet.com' to='nurse@capulet.com' type='subscribed'/>
|
|
]]></example>
|
|
<p>For PEP purposes, this is equivalent to the following pubsub subscription exchange:</p>
|
|
<example caption='Entity subscribes to a collection node'><![CDATA[
|
|
<iq type='set'
|
|
from='nurse@capulet.com/chamber'
|
|
to='juliet@capulet.com
|
|
id='collsub'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<subscribe jid='nurse@capulet.com'/>
|
|
<options>
|
|
<x xmlns='jabber:x:data'>
|
|
<field var='FORM_TYPE' type='hidden'>
|
|
<value>http://jabber.org/protocol/pubsub#subscribe_options</value>
|
|
</field>
|
|
<field var='pubsub#subscription_type'>
|
|
<value>items</value>
|
|
</field>
|
|
<field var='pubsub#subscription_depth'>
|
|
<value>all</value>
|
|
</field>
|
|
</x>
|
|
</options>
|
|
</pubsub>
|
|
</iq>
|
|
|
|
<iq type='result' from='juliet@capulet.com' to='nurse@capulet.com/chamber' id='collsub'/>
|
|
]]></example>
|
|
<p>Note: Automated pubsub subscriptions MUST be based on the JID contained in the 'from' address of the presence subscription request, which for IM contacts will be a bare JID (&BAREJID;).</p>
|
|
</section1>
|
|
|
|
<section1 topic='Account Owner Publishing' anchor='owner-publish'>
|
|
<p>An account owner publishes an item to a node by following the protocol specified in <cite>XEP-0060</cite>:</p>
|
|
<example caption='Account owner publishes item'><![CDATA[
|
|
<iq from='juliet@capulet.com/balcony' type='set' id='pub1'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<publish node='http://jabber.org/protocol/tune'>
|
|
<item>
|
|
<tune xmlns='http://jabber.org/protocol/tune'>
|
|
<artist>Gerald Finzi</artist>
|
|
<title>Introduction (Allegro vigoroso)</title>
|
|
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
|
|
<track>1</track>
|
|
<length>255</length>
|
|
</tune>
|
|
</item>
|
|
</publish>
|
|
</pubsub>
|
|
</iq>
|
|
]]></example>
|
|
<p>As a result, the account owner's server generates notifications and sends them to all subscribers who have requested or are interested in the data as described in the <link url='#notifications'>Contact Notification Filtering</link> and <link url='#notifications'>Generating Notifications</link> sections of this document.</p>
|
|
<p>The server MUST set the 'from' address on the notification to the bare JID (&BAREJID;) of the account owner (in this example, "juliet@capulet.com"). When sending notifications to an entity that has a presence subscription to the account owner, the server SHOULD include an &xep0033; "replyto" extension specifying the publishing resource (in this example, "juliet@capulet.com/balcony"); this enables the subscriber's client to differentiate between information received from each of the account owner's resources (for example, different resources may be in different places and therefore may need to specify distinct geolocation data). However, a server MUST NOT include the "replyto" address when sending a notification to an entity that does not have a presence subscription to the account owner. In addition, any errors related to the notification MUST be directed to the JID of the 'from' address on the notification (i.e., the bare JID) so that bounce processing can be handled by the PEP service rather than by the publishing client.</p>
|
|
<p>Assuming that all three entities previously mentioned would receive the notifications, the PEP service would generate the following stanzas:</p>
|
|
<example caption='Server sends notification to subscribers'><![CDATA[
|
|
<message from='juliet@capulet.com'
|
|
to='benvolio@montague.net'
|
|
type='headline'
|
|
id='foo'>
|
|
<event xmlns='http://jabber.org/protocol/pubsub#event'>
|
|
<items node='http://jabber.org/protocol/tune'>
|
|
<item>
|
|
<tune xmlns='http://jabber.org/protocol/tune'>
|
|
<artist>Gerald Finzi</artist>
|
|
<title>Introduction (Allegro vigoroso)</title>
|
|
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
|
|
<track>1</track>
|
|
<length>255</length>
|
|
</tune>
|
|
</item>
|
|
</items>
|
|
</event>
|
|
</message>
|
|
|
|
<message from='juliet@capulet.com'
|
|
to='nurse@capulet.com/chamber'
|
|
type='headline'
|
|
id='foo'>
|
|
<event xmlns='http://jabber.org/protocol/pubsub#event'>
|
|
<items node='http://jabber.org/protocol/tune'>
|
|
<item>
|
|
<tune xmlns='http://jabber.org/protocol/tune'>
|
|
<artist>Gerald Finzi</artist>
|
|
<title>Introduction (Allegro vigoroso)</title>
|
|
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
|
|
<track>1</track>
|
|
<length>255</length>
|
|
</tune>
|
|
</item>
|
|
</items>
|
|
</event>
|
|
<addresses xmlns='http://jabber.org/protocol/address'>
|
|
<address type='replyto' jid='juliet@capulet.com/balcony'/>
|
|
</addresses>
|
|
</message>
|
|
|
|
<message from='juliet@capulet.com'
|
|
to='romeo@montague.net/orchard'
|
|
type='headline'
|
|
id='foo'>
|
|
<event xmlns='http://jabber.org/protocol/pubsub#event'>
|
|
<items node='http://jabber.org/protocol/tune'>
|
|
<item>
|
|
<tune xmlns='http://jabber.org/protocol/tune'>
|
|
<artist>Gerald Finzi</artist>
|
|
<title>Introduction (Allegro vigoroso)</title>
|
|
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
|
|
<track>1</track>
|
|
<length>255</length>
|
|
</tune>
|
|
</item>
|
|
</items>
|
|
</event>
|
|
<addresses xmlns='http://jabber.org/protocol/address'>
|
|
<address type='replyto' jid='juliet@capulet.com/balcony'/>
|
|
</addresses>
|
|
</message>
|
|
]]></example>
|
|
<p>Note the 'to' addresses: the notification to Benvolio is addressed to "benvolio@montague.net" (bare JID) since the PEP service does not have presence information about the subscriber, whereas the notifications to the Nurse and to Romeo are addressed to the full JIDs of those subscribers.</p>
|
|
</section1>
|
|
|
|
<section1 topic='Contact Notification Filtering' anchor='contact-filter'>
|
|
<p>A contact may not want to receive notifications for all payload types. A contact SHOULD signal its preferences to the account owner's server by including <cite>XEP-0115</cite> information that specifies the namespaces for which the contact wishes to receive notifications (if any).</p>
|
|
<p>In order to make this possible, all possible payload namespaces can be appended with the string "+notify" to indicate that the contact wishes to receive notifications for the payload format. Thus if Romeo wants to receive notifications for activity data and geolocation data but not tune data, his client would advertise support for the following namespaces in the disco#info results it sends: <note>Including, say, the 'http://jabber.org/protocol/geoloc' namespace indicates that the client understands the geolocation namespace, whereas including the 'http://jabber.org/protocol/geoloc+notify' namespace indicates that the client wishes to receive notifications related to geolocation.</note></p>
|
|
<ul>
|
|
<li>http://jabber.org/protocol/activity+notify</li>
|
|
<li>http://jabber.org/protocol/geoloc+notify</li>
|
|
</ul>
|
|
<p>This set of namespaces would then be advertised as a <cite>XEP-0115</cite> "ext" value, such as the following:</p>
|
|
<example caption='Contact sends presence with caps'><![CDATA[
|
|
<presence from='romeo@montague.net/orchard'>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
node='http://www.chatopus.com/'
|
|
ver='2.1'
|
|
ext='foobar pres+'/>
|
|
</presence>
|
|
]]></example>
|
|
<p>Note: In <cite>XEP-0115</cite>, the "ext" values are opaque strings with no semantic meaning.</p>
|
|
<p>It is the responsibility of the account owner's server to cache <cite>XEP-0115</cite> information (including "ext" values and their associated namespaces). When the server receives presence from a contact, it MUST check that presence information for entity capabilities data and correlate that data with the desired namespaces for the contact's client. The server MUST NOT send notifications related to any data formats that the contact's client has not asked for via the relevant "namespace+notify" disco#info feature. This enables a client to turn off all notifications (e.g., because of bandwidth restrictions) and to easily receive all desired data formats simply by adding support for the appropriate "namespace+notify" combination in its disco#info results and client capabililies. However, it also implies that a client can request notifications only on a global basis and cannot request, say, mood information only from certain contacts in the user's roster. Community consensus is that this is an acceptable tradeoff. Also, note that this works only if the account owner has a presence subscription to the contact and the contact has a presence subscription to the account owner.</p>
|
|
<p>Some examples may help to illustrate the concept of notification filtering. Here we show presence generated by two of the contacts listed above (benvolio@montague.net does have any presence subscriptions to or from juliet@capulet.com and therefore is not involved in these protocol flows).</p>
|
|
<example caption='Presence with caps'><![CDATA[
|
|
<presence from='nurse@capulet.com/chamber'>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
node='http://exodus.jabberstudio.org/caps'
|
|
ver='0.9'
|
|
ext='asdf fdsa bar baz'/>
|
|
</presence>
|
|
|
|
<presence from='romeo@montague.net/orchard'>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
node='http://www.chatopus.com/ec'
|
|
ver='2.1'
|
|
ext='foobar pres+'/>
|
|
</presence>
|
|
]]></example>
|
|
<p>We assume that Juliet's server doesn't know anything about these capabilities, so it sends service discovery information requests to each of the clients on Juliet's behalf (realistically, the capulet.com server will quickly build up a cache of client capabilities, with the result that it will not need to send these service discovery requests):</p>
|
|
<example caption='Account server queries contact'><![CDATA[
|
|
<iq from='juliet@capulet.com'
|
|
to='nurse@capulet.com/chamber'
|
|
type='get'
|
|
id='disco123'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'
|
|
node='http://exodus.jabberstudio.org/caps#0.9'/>
|
|
</iq>
|
|
|
|
<iq from='nurse@capulet.com/chamber'
|
|
to='juliet@capulet.com'
|
|
type='result'
|
|
id='disco123'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'
|
|
node='http://exodus.jabberstudio.org/caps#0.9'/>
|
|
<feature var='http://jabber.org/protocol/tune'/>
|
|
<feature var='http://jabber.org/protocol/tune+notify'/>
|
|
<feature var='http://jabber.org/protocol/activity'/>
|
|
<feature var='http://jabber.org/protocol/activity+notify'/>
|
|
<feature var='http://jabber.org/protocol/geoloc'/>
|
|
<feature var='http://jabber.org/protocol/geoloc+notify'/>
|
|
</query>
|
|
</iq>
|
|
]]></example>
|
|
<example caption='Account server queries contact'><![CDATA[
|
|
<iq from='juliet@capulet.com'
|
|
to='romeo@montague.net/orchard'
|
|
type='get'
|
|
id='disco234'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'
|
|
node='http://www.chatopus.com/ec#2.1'/>
|
|
</iq>
|
|
|
|
<iq from='romeo@montague.net/orchard'
|
|
to='juliet@capulet.com'
|
|
type='result'
|
|
id='disco234'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info'
|
|
node='http://www.chatopus.com/ec#2.1'/>
|
|
<feature var='http://jabber.org/protocol/tune'/>
|
|
<feature var='http://jabber.org/protocol/activity'/>
|
|
<feature var='http://jabber.org/protocol/geoloc'/>
|
|
<feature var='http://jabber.org/protocol/geoloc+notify'/>
|
|
</query>
|
|
</iq>
|
|
]]></example>
|
|
<p>Now we revisit account owner publication and server generation of notifications, with filtering enabled because the server has caps information:</p>
|
|
<ul>
|
|
<li><p>If Juliet publishes a tune item to the open-access "http://jabber.org/protocol/tune" node, her server will send notifications to <benvolio@montague.net> (bare JID) and to <nurse@capulet.com/chamber> (full JID) but not to <romeo@montague.net/orchard>.</p></li>
|
|
<li><p>If Juliet publishes an activity item to the presence-access "http://jabber.org/protocol/activity" node, her server will send notifications only to <nurse@capulet.com/chamber>.</p></li>
|
|
<li><p>If Juliet publishes a geolocation item to the roster-access "http://jabber.org/protocol/geoloc" node, her server will send notifications only to <romeo@montague.net/orchard>.</p></li>
|
|
</ul>
|
|
</section1>
|
|
|
|
<section1 topic='Generating Notifications' anchor='notifications'>
|
|
<section2 topic='Number of Notifications' anchor='notifications-num'>
|
|
<ol start='1'>
|
|
<li><p>If a subscriber subscribed using a full JID (&FULLJID;), domain identifier (&DOMAIN;), or domain plus resource (&DOMAINRES;), a PEP service MUST send one notification only, addressed to the subscribed JID.</p></li>
|
|
<li><p>If a subscriber subscribed using a bare JID (&BAREJID;) and a PEP service does not have appropriate presence information about the subscriber, a PEP service MUST send at most one notification, addressed to the bare JID (&BAREJID;) of the subscriber, and MAY choose not to send any notification. (By "appropriate presence information" is meant an available presence stanza with non-negative priority and <cite>XEP-0115</cite> data that indicates interest in the relevant data format.)</p></li>
|
|
<li><p>If a subscriber subscribed using a bare JID (&BAREJID;) and a PEP service has appropriate presence information about the subscriber, the PEP service MUST send one notification to the full JID (&FULLJID;) of each of the subscriber's available resources that have specified non-negative presence priority and included <cite>XEP-0115</cite> information that indicates an interest in the data format.</p></li>
|
|
</ol>
|
|
</section2>
|
|
<section2 topic='When to Generate Notifications' anchor='notifications-when'>
|
|
<ol start='1'>
|
|
<li><p>When an account owner publishes an item to a node, a PEP service MUST generate a notification and send it to all appropriate subscribers (where the number of notifications is determined by the foregoing rules).</p></li>
|
|
<li><p>When a PEP service receives initial presence information from a subscriber's resource with a non-negative priority and including <cite>XEP-0115</cite> information that indicates an interest in the data format, it MUST generate a notification containing the last published item for that node and send it to the newly-available resource.</p></li>
|
|
<li><p>As an exception to the foregoing MUST rules, a PEP service MUST NOT send notifications to a subscriber if the user has blocked the subscriber from receiving all or any kinds of stanza (presence, message, IQ, or any combination thereof) using communiations blocking as specified in <cite>XMPP IM</cite>.</p></li>
|
|
</ol>
|
|
</section2>
|
|
</section1>
|
|
|
|
<section1 topic='Sending the Last Published Item' anchor='last'>
|
|
<p>As described in the <link url='#notifications'>Generating Notifications</link> section of this document, a PEP service MUST send the last published item to all new subscribers and to all newly-available resources for each subscriber. <note>That is, the default value of the "pubsub#send_last_published_item" node configuration field must be "on_sub_and_presence"; this behavior essentially mimics the functionality of presence as defined in <cite>XMPP IM</cite>.</note></p>
|
|
<example caption='Subscriber sends presence from newly-available resource'><![CDATA[
|
|
<presence from='romeo@montague.net/orchard'>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
node='http://www.chatopus.com/ec'
|
|
ver='2.1'
|
|
ext='foobar pres+'/>
|
|
</presence>
|
|
]]></example>
|
|
<example caption='Subscriber's server sends presence from newly-available resource to publisher's bare JID (i.e., PEP service)'><![CDATA[
|
|
<presence from='romeo@montague.net/orchard' to='juliet@capulet.com'>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
node='http://www.chatopus.com/ec'
|
|
ver='2.1'
|
|
ext='foobar pres+'/>
|
|
</presence>
|
|
]]></example>
|
|
<example caption='PEP service sends last published item to newly-available resource'><![CDATA[
|
|
<message from='juliet@capulet.com'
|
|
to='romeo@montague.net/orchard'
|
|
type='headline'
|
|
id='foo'>
|
|
<event xmlns='http://jabber.org/protocol/pubsub#event'>
|
|
<items node='http://jabber.org/protocol/tune'>
|
|
<item>
|
|
<tune xmlns='http://jabber.org/protocol/tune'>
|
|
<artist>Gerald Finzi</artist>
|
|
<title>Introduction (Allegro vigoroso)</title>
|
|
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
|
|
<track>1</track>
|
|
<length>255</length>
|
|
</tune>
|
|
</item>
|
|
</items>
|
|
</event>
|
|
<x xmlns='jabber:x:delay' stamp='20031213T23:58:37'/>
|
|
</message>
|
|
]]></example>
|
|
</section1>
|
|
|
|
<section1 topic='Private Data Storage' anchor='privatedata'>
|
|
<p>As noted, PEP services may be used to implement private data storage, such as defined in &xep0049;. A future version of this document will specify this usage in more detail.</p>
|
|
</section1>
|
|
|
|
<section1 topic='Recommended Defaults' anchor='defaults'>
|
|
<p>A PEP service MUST:</p>
|
|
<ul>
|
|
<li>Support the node discovery, node creation, node deletion, publish item, subscribe, unsubscribe, and item retrieval use cases specified in <cite>XEP-0060</cite>.</li>
|
|
<li>Support the "owner" and "subscriber" affiliations.</li>
|
|
<li>Support the "presence" access model and set it to the default.</li>
|
|
<li>Support the "open", "roster", and "whitelist" access models.</li>
|
|
<li>Treat the account owner's bare JID (&BAREJID;) as a collection node (i.e., as the root collection node for the account's virtual pubsub service).</li>
|
|
<li>Deliver payloads (if included) in all notifications.</li>
|
|
<li>Send the last publish item as described above.</li>
|
|
<li>Support the 'deliver_notifications' and 'send_last_published_item' configuration options.</li>
|
|
</ul>
|
|
<p>A PEP service MAY support other use cases, affiliations, access models, and features, but such support is OPTIONAL.</p>
|
|
</section1>
|
|
|
|
<section1 topic='Implementation Notes' anchor='imple'>
|
|
<section2 topic='Cancelling Subscriptions' anchor='impl-subscriptions'>
|
|
<p>In order to ensure appropriate access to information published at nodes of type "presence" and "roster", a PEP service MUST re-calculate access controls when:</p>
|
|
<ol start='1'>
|
|
<li>A presence subscription state changes (e.g., when a subscription request is approved).</li>
|
|
<li>A roster item is modified (e.g., when the item is moved to a new roster group).</li>
|
|
</ol>
|
|
<p>If the modification results in a loss of access, the service MUST cancel the entity's subscription. In addition, the service MAY send a message to the (former) subscriber informing it of the cancellation (for information about the format of messages sent to notify subscribers of subscription cancellation, see the "Notification of Subscription Denial or Cancellation" section of <cite>XEP-0060</cite>).</p>
|
|
</section2>
|
|
</section1>
|
|
|
|
<section1 topic='Security Considerations' anchor='security'>
|
|
<p>A PEP service MAY enforce additional privacy and security policies when determining whether an entity is allowed to subscribe to a node or retrieve items from a node; however, any such policies shall be considered specific to an implementation or deployment and are out of scope for this document.</p>
|
|
</section1>
|
|
|
|
<section1 topic='IANA Considerations' anchor='iana'>
|
|
<p>This document requires no interaction with &IANA;.</p>
|
|
</section1>
|
|
|
|
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
|
<section2 topic='Service Discovery Category/Type' anchor='registrar-disco'>
|
|
<p>The ®ISTRAR; includes a category of "pubsub" in its registry of Service Discovery identities (see &DISCOCATEGORIES;); as a result of this document, the Registrar includes a type of "pep" to that category.</p>
|
|
<p>The registry submission is as follows:</p>
|
|
<code><![CDATA[
|
|
<category>
|
|
<name>pubsub</name>
|
|
<type>
|
|
<name>pep</name>
|
|
<desc>
|
|
A personal eventing service that supports the
|
|
publish-subscribe subset defined in XEP-0163.
|
|
</desc>
|
|
<doc>XEP-0163</doc>
|
|
</type>
|
|
</category>
|
|
]]></code>
|
|
</section2>
|
|
</section1>
|
|
|
|
<section1 topic='XML Schema' anchor='schema'>
|
|
<p>Because Personal Eventing via Pubsub simply reuses the protocol specified in <cite>XEP-0060</cite>, a separate schema is not needed.</p>
|
|
</section1>
|
|
|
|
<section1 topic='Acknowledgements' anchor='ack'>
|
|
<p>The authors wish to thank the participants in the XMPP Interoperability Testing Event held July 24 and 25, 2006, who provided valuable feedback that resulted in radical simplification of the protocol.</p>
|
|
</section1>
|
|
|
|
</xep>
|