1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-21 16:55:07 -05:00
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@742 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2007-04-10 19:42:51 +00:00
parent 3db71d4909
commit 78c0e01a6e

View File

@ -28,10 +28,10 @@
&stpeter; &stpeter;
&remko; &remko;
<revision> <revision>
<version>1.3pre1</version> <version>1.3</version>
<date>in progress, last updated 2007-03-19</date> <date>2007-04-10</date>
<initials>psa</initials> <initials>psa/rt/jjh</initials>
<remark><p>Added developer-friendly introduction; specified that ext names must be stable across application versions; further clarified examples; added stream feature use case.</p></remark> <remark><p>Added developer-friendly introduction; specified that ext names must be stable across application versions; further clarified examples; added stream feature use case; removed message example (send directed presence instead).</p></remark>
</revision> </revision>
<revision> <revision>
<version>1.2</version> <version>1.2</version>
@ -97,7 +97,7 @@
</revision> </revision>
</header> </header>
<section1 topic='Introduction' anchor='intro'> <section1 topic='Introduction' anchor='intro'>
<section2 topic='Motivation' anchor='intro-motivation'> <section2 topic='Motivation' anchor='motivation'>
<p>It is often desirable for a Jabber/XMPP application (commonly but not necessarily a client) to take different actions depending on the capabilities of another application from which it receives presence information. Examples include:</p> <p>It is often desirable for a Jabber/XMPP application (commonly but not necessarily a client) to take different actions depending on the capabilities of another application from which it receives presence information. Examples include:</p>
<ul> <ul>
<li>Showing a different set of icons depending on the capabilities of other clients.</li> <li>Showing a different set of icons depending on the capabilities of other clients.</li>
@ -107,14 +107,14 @@
</ul> </ul>
<p>Some older Jabber clients send one &xep0030; and one &xep0092; request to each entity from which they received presence after login. That "disco+version flood" results in an excessive use of bandwidth and is impractical on a larger scale, particularly for users or applications with large rosters. Therefore this document proposes a more robust and scalable solution: namely, a presence-based mechanism <note>This proposal is not limited to clients, and can be used by any entity that exchanges presence with another entity, e.g., a gateway. However, this document uses the example of clients throughout.</note> for exchanging information about entity capabilities. Clients SHOULD NOT engage in the older "disco+version flood" behavior and instead SHOULD use Entity Capabilities as specified herein.</p> <p>Some older Jabber clients send one &xep0030; and one &xep0092; request to each entity from which they received presence after login. That "disco+version flood" results in an excessive use of bandwidth and is impractical on a larger scale, particularly for users or applications with large rosters. Therefore this document proposes a more robust and scalable solution: namely, a presence-based mechanism <note>This proposal is not limited to clients, and can be used by any entity that exchanges presence with another entity, e.g., a gateway. However, this document uses the example of clients throughout.</note> for exchanging information about entity capabilities. Clients SHOULD NOT engage in the older "disco+version flood" behavior and instead SHOULD use Entity Capabilities as specified herein.</p>
</section2> </section2>
<section2 topic='How It Works' anchor='intro-how'> <section2 topic='How It Works' anchor='howitworks'>
<p>This section provides a friendly, non-normative introduction to the workings of entity capabilities.</p> <p>This section provides a friendly, non-normative introduction to the workings of entity capabilities.</p>
<p>Suppose you are a Shakespearean character named Juliet and one of your contacts, a handsome fellow named Romeo, becomes available. His client wants to publish its capabilities, and does this by adding a &lt;c/&gt; element to its presence packets. As a result, your client receives the following presence packet:</p> <p>Imagine that you are a Shakespearean character named Juliet and one of your contacts, a handsome fellow named Romeo, becomes available. His client wants to publish its capabilities, and does this by adding a &lt;c/&gt; element to its presence packets. As a result, your client receives the following presence packet:</p>
<code><![CDATA[ <code><![CDATA[
<presence from='romeo@montague.net/home'> <presence from='romeo@montague.net/home'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps' node='http://exodus.jabberstudio.org/caps'
ver='0.9' /> ver='0.9'/>
</presence> </presence>
]]></code> ]]></code>
<p>The 'node' attribute represents the client Romeo is using, and the 'ver' attribute represents the specific version of this client. At this point, your client has no idea what the capabilities are of someone with a client string 'http://exodus.jabberstudio.org/caps' and a version string '0.9'. Your client therefore sends a query to Romeo, asking what his client version can do (using service discovery):</p> <p>The 'node' attribute represents the client Romeo is using, and the 'ver' attribute represents the specific version of this client. At this point, your client has no idea what the capabilities are of someone with a client string 'http://exodus.jabberstudio.org/caps' and a version string '0.9'. Your client therefore sends a query to Romeo, asking what his client version can do (using service discovery):</p>
@ -142,7 +142,7 @@
<presence from='benvolio@capulet.com/230193'> <presence from='benvolio@capulet.com/230193'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps' node='http://exodus.jabberstudio.org/caps'
ver='0.9' /> ver='0.9'/>
</presence> </presence>
]]></code> ]]></code>
<p>Now your client automatically knows that Benvolio can do MUC, without needing to ask him explicitly via service discovery.</p> <p>Now your client automatically knows that Benvolio can do MUC, without needing to ask him explicitly via service discovery.</p>
@ -151,7 +151,7 @@
<presence from='bob@initech.com/Home'> <presence from='bob@initech.com/Home'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps' node='http://exodus.jabberstudio.org/caps'
ver='0.10' /> ver='0.10'/>
</presence> </presence>
]]></code> ]]></code>
<p>... or the following presence ...</p> <p>... or the following presence ...</p>
@ -159,7 +159,7 @@
<presence from='bard@shakespeare.lit/globe'> <presence from='bard@shakespeare.lit/globe'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://psi-im.org/caps' node='http://psi-im.org/caps'
ver='0.9' /> ver='0.9'/>
</presence> </presence>
]]></code> ]]></code>
<p>... you have no information about what this contact's client is capable of (as he is using a different client/version), and you therefore need to query his capabilities explicitly again.</p> <p>... you have no information about what this contact's client is capable of (as he is using a different client/version), and you therefore need to query his capabilities explicitly again.</p>
@ -169,10 +169,10 @@
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps' node='http://exodus.jabberstudio.org/caps'
ver='0.9' ver='0.9'
ext='csn' /> ext='csn'/>
</presence> </presence>
]]></code> ]]></code>
<p>In this case, Benvolio is using an extension that his client calls 'csn'. Again, your client has no clue what 'csn' means, as it is a name arbitrarily chosen by Benvolio's client. It therefore queries Benvolio's client to find out what a client 'http://exodus.jabberstudio.org/caps' means when it says it supports 'csn'.</p> <p>In this case, Benvolio is using an extension that his client calls 'csn'. Again, your client has no clue what 'csn' means, as it is a name arbitrarily chosen by Benvolio's client. It therefore queries Benvolio's client to find out what a client 'http://exodus.jabberstudio.org/caps' means when it says it supports 'csn'. It does this by sending a disco#info request to the node#ext (not the node#ver as was done to find the base capabilities):</p>
<code><![CDATA[ <code><![CDATA[
<iq type='get' to='romeo@montague.net/home' id='2'> <iq type='get' to='romeo@montague.net/home' id='2'>
<query xmlns='http://jabber.org/protocol/disco#info' <query xmlns='http://jabber.org/protocol/disco#info'
@ -188,16 +188,17 @@
</query> </query>
</iq> </iq>
]]></code> ]]></code>
<p>Now, your client knows that Benvolio's client (and anyone using the same client node as Benvolio and extension 'csn') supports chat state notifications. On the other hand, suppose Bill logs on:</p> <p>Now, your client knows that Benvolio's client (and anyone using the same client node as Benvolio and extension 'csn', since the 'ext' values MUST be stable across client versions) supports chat state notifications. <em>The sum total of what Benvolio's client supports is the set of features advertised in disco#info responses to the node#ver (base features) and the set of features advertised in disco#info responses to each node#ext (extension features).</em></p>
<p>However, suppose Bill logs on:</p>
<code><![CDATA[ <code><![CDATA[
<presence from='bard@shakespeare.lit/globe'> <presence from='bard@shakespeare.lit/globe'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://psi-im.org/caps' node='http://psi-im.org/caps'
ver='0.9' ver='0.9'
ext='csn' /> ext='csn'/>
</presence> </presence>
]]></code> ]]></code>
<p>Although you know that 'csn' meant "chat state notifications" for Benvolio (and for everyone using the same client as Benvolio), you do not know what this means for Bill, because he is using a different client. So you query his client:</p> <p>Although you know that 'csn' meant "chat state notifications" for Benvolio (and for everyone using the same client as Benvolio), you do not know what this means for Bill, because he is using a different client! So you need to query his client:</p>
<code><![CDATA[ <code><![CDATA[
<iq type='get' to='bard@shakespeare.lit/globe' id='3'> <iq type='get' to='bard@shakespeare.lit/globe' id='3'>
<query xmlns='http://jabber.org/protocol/disco#info' <query xmlns='http://jabber.org/protocol/disco#info'
@ -213,7 +214,7 @@
</query> </query>
</iq> </iq>
]]></code> ]]></code>
<p>... reveals that this client uses 'csn' to denote the capability of "stanza session negotiation" (formerly known as "chat session negotiation").</p> <p>... reveals that this client uses 'csn' to denote the capability of "stanza session negotiation" (formerly known as "chat session negotiation"). So although the 'ext' values are stable for each client (and for all versions thereof), they are not stable across different clients.</p>
</section2> </section2>
</section1> </section1>
<section1 topic='Assumptions' anchor='assumptions'> <section1 topic='Assumptions' anchor='assumptions'>
@ -355,32 +356,6 @@
<p>All of the responses to the <strong>disco#info</strong> queries SHOULD be cached. If a particular entity cannot store the responses, it SHOULD NOT make the requests. An entity SHOULD NOT make the service discovery requests unless the information is required for some local functionality. An entity MUST NOT ever make a request to another entity that has the same version of the same application as the requesting entity, except for extensions that are not supported by the requestor's installation (e.g., one "Exodus 0.9" client MUST NOT query another "Exodus 0.9" client unless the second client has advertised an extension or plugin that the first client does not have).</p> <p>All of the responses to the <strong>disco#info</strong> queries SHOULD be cached. If a particular entity cannot store the responses, it SHOULD NOT make the requests. An entity SHOULD NOT make the service discovery requests unless the information is required for some local functionality. An entity MUST NOT ever make a request to another entity that has the same version of the same application as the requesting entity, except for extensions that are not supported by the requestor's installation (e.g., one "Exodus 0.9" client MUST NOT query another "Exodus 0.9" client unless the second client has advertised an extension or plugin that the first client does not have).</p>
</section2> </section2>
<section2 topic='Sending Messages to Unsubscribed Entities' anchor='sendmsg'>
<p>If an application sends message to an entity from which it has not received presence, it MAY choose to append a capabilities annotation to <em>only</em> the first message sent to that entity within a particular conversation thread or "session" (alternatively, two users who normally do not share presence can send directed presence, either without prompting or as negotiated via &xep0155;). The application MUST NOT append a capabilities annotation to later messages unless its capabilities have changed (e.g., the value of the 'ext' has changed as described above) and MUST NOT send the annotation to entities from which it has received presence. Also, an application MUST NOT send the capabilities annotation to entities which are in a user's roster (or equivalent entity store, as in a gateway) with subscription='both' or subscription='to' (since presence would have been received from these entities if they were online).</p>
<example caption='Message including capabilities'><![CDATA[
<message to='romeo@example.net'
from='juliet@example.com/balcony'>
<thread>thread1</thread>
<body>Art thou not Romeo, and a Montague?</body>
<c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps'
ver='0.9'
ext='1g'/>
</message>
]]></example>
<p>If the recipient responds to one of these annotated messages, the first message back in the other direction SHOULD be annotated with capabilities.</p>
<example caption='Response message including capabilities'><![CDATA[
<message from='romeo@example.net/orchard'
to='juliet@example.com/balcony'>
<thread>thread1</thread>
<body>Neither, fair saint, if either thee dislike.</body>
<c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps'
ver='0.9'/>
</message>
]]></example>
<p>Alternatively, unsubscribed entities MAY send directed presence to each other, for which the same rules apply as listed above for messages.</p>
</section2>
<section2 topic='Stream Feature' anchor='stream'> <section2 topic='Stream Feature' anchor='stream'>
<p>A server MAY include its own entity capabilities in a stream feature element so that connecting clients and peer servers do not need to send service discovery requests each time they connect:</p> <p>A server MAY include its own entity capabilities in a stream feature element so that connecting clients and peer servers do not need to send service discovery requests each time they connect:</p>
<example caption='Stream feature element including capabilities'><![CDATA[ <example caption='Stream feature element including capabilities'><![CDATA[
@ -418,6 +393,7 @@
</section1> </section1>
<section1 topic='Implementation Notes' anchor='impl'> <section1 topic='Implementation Notes' anchor='impl'>
<p>If two entities exchanges messages but they do not normally exchange presence (i.e., via presence subscription), the entities MAY choose to send directed presence to each other, where the presence information SHOULD be annotated with the same capabilities information as each entity sends in broadcasted presence.</p>
<p>If capabilities information has not been received from another entity, an application MUST assume that the other entity does not support capabilities.</p> <p>If capabilities information has not been received from another entity, an application MUST assume that the other entity does not support capabilities.</p>
</section1> </section1>