XEP-0030

来自Jabber/XMPP中文翻译计划
(版本间的差异)
跳转到: 导航, 搜索
(基本协议)
 
(未显示2个用户的79个中间版本)
第10行: 第10行:
 
作者: Joe Hildebrand, Peter Millard, Ryan Eatmon, Peter Saint-Andre
 
作者: Joe Hildebrand, Peter Millard, Ryan Eatmon, Peter Saint-Andre
  
XMPP扩展协议的版权(1999-2008)归XMPP标准化基金会(XSF)所有
+
版权: © 1999 - 2010 XMPP标准化基金会(XSF). 参见[[XEP-0030#附录C:法律通告|法律通告]].
 
+
版权: © 1999 - 2010 XMPP标准化基金会(XSF). 参见法律通告.
+
  
 
状态: 最终
 
状态: 最终
第23行: 第21行:
  
 
注意: 这里定义的协议是XMPP标准化基金会的一个'''最终标准''',对于实现和布署来说可以被认为是一个稳定技术.
 
注意: 这里定义的协议是XMPP标准化基金会的一个'''最终标准''',对于实现和布署来说可以被认为是一个稳定技术.
 
 
 
本文档定义了XMPP协议扩展用于发现(1)Jabber实体的信息和(2)与这些实体相关的细节。
 
 
'''注意''' 此处定义的协议是XMPP标准基金会的最终标准,可作为稳定技术用于开发和部署。
 
 
'''文档信息'''
 
 
系列:[[:Category:XMPP扩展|XEP]]
 
 
序号:[http://www.xmpp.org/extensions/xep-0030.html 0030]
 
 
发布者:[[XMPP标准基金会]]
 
 
状态:[http://www.xmpp.org/extensions/xep-0001.html#states-Final 终结版]
 
 
类型:[http://www.xmpp.org/extensions/xep-0001.html#types-Standards%20Track 标准跟踪]
 
 
版本:2.3
 
 
最后更新:2007-02-15
 
 
批准机构:[[XMPP理事会]]
 
 
依赖标准:[[RFC3920|XMPP Core]]
 
 
替代标准:XEP-0011, XEP-0094
 
 
被替代标准:无
 
 
缩略名:disco
 
 
命名空间disco#info的XML方案(Schema)[http://www.xmpp.org/schemas/disco-info.xsd]
 
 
命名空间disco#items的XML方案(Schema)[http://www.xmpp.org/schemas/disco-items.xsd]
 
 
'''作者信息'''
 
 
'''法律通告'''
 
 
'''讨论地点'''
 
 
'''相关的XMPP'''
 
 
'''术语的一致性'''
 
  
 
==绪论==
 
==绪论==
  
在Jabber网络中发现实体相关信息的能力是极有价值的。这些信息包括实体支持的特性或支持的协议、实体的类型或身份、同原实体以某种方式相联系的另外一些实体等(这些实体通常当作“父”实体的“子”实体)。虽然XMPP核心并没有定义怎样做的机制,但在Jabber社区内,过去已经有几个协议用在了服务发现、特定的Jabber浏览\[2\]和代理信息\[3\]上。然而,这些协议总使人感觉不那么合适,其原因如下:
+
在Jabber网络中发现实体相关信息的能力是极有价值的。这些信息包括实体支持的特性或支持的协议、实体的类型或身份、同原实体以某种方式相联系的另外一些实体等(这些实体通常当作“父”实体的“子”实体)。虽然[[RFC3920|XMPP Core]] [[XEP-0030#附录G:备注|1]]并没有定义怎样做的机制,但在Jabber社区内,过去已经有几个协议用在了服务发现上,特别是 [http://xmpp.org/extensions/xep-0011.html Jabber Browsing] [[XEP-0030#附录G:备注|2]]和[http://xmpp.org/extensions/xep-0094.html Agent Information] [[XEP-0030#附录G:备注|3]]上。然而,这些协议总使人感觉不那么合适,其原因如下:
  
# Jabber浏览和代理信息都不容易扩展。例如,在XEP-0011中列出JID类型的种类及子类都明确地定义为唯一的正式种类,向列表加入新的JID类型都要修改XEP-0011。而Jabber浏览规范不允许用非正式种类和以‘x-’打头的类型,这会产生移植问题。这种适应性的缺乏违反了Jabber社区的协议设计原则核心之一\[4\]。
+
# Jabber Browsing 和 Agent Information 都不容易扩展。例如,在XEP-0011中列出JID类型的种类及子类都明确地定义为唯一的正式种类,向列表加入新的JID类型都要修改XEP-0011。而Jabber Browsing规范允许用非正式种类和以‘x-’打头的类型,这会产生移植问题。这种适应性的缺乏违反了Jabber社区的核心[http://xmpp.org/extensions/xep-0134.html XMPP协议设计原则] [[XEP-0030#附录G:备注|4]]之一
# 代理信息中,没有告知所支持的特性的方法。虽然Jabber浏览包含了这样的机制,但表达一个特性的有效性的唯一方法是告知一个所支持的名字空间。然而,有些特性也许并非唯一地对应一个协议名字空间,它只是特性的一个实现,但并不唯一。
+
# 在 Agent Information 协议中,没有声明所支持的特性的方法。虽然Jabber Browsing包含了这样的机制,但表达一个特性的有效性的唯一方法是声明一个所支持的名字空间。然而,有些特性也许并非唯一地对应一个协议名字空间,它只是特性的一个实现,但并是唯一的一个。
# 一个Jabber浏览结果返回一个组合,由(1)Jabber实体支持的名字空间,(2)与Jabber实体相关联的细节,(3)相关细节支持的名字空间组成。这种方法混淆了信息级别,要求父节点知晓子节点的一切,也就引入了极大的混乱。
+
# 一个Jabber Browsing 结果返回一个组合,由(1)Jabber实体支持的名字空间,(2)与Jabber实体相关联的条目,(3)相关条目支持的名字空间组成。这种方法混淆了信息级别,要求父节点知晓子节点的一切,也就引入了极大的混乱。
# 在Jabber浏览和代理信息中,要求细节(items)必须可定址为JID;然而,这在有些应用中是作不到的。
+
# 在Jabber Browsing 和 Agent Information中,要求条目们(items)必须可寻址为JIDs;然而,这在有些应用中是做不到的。
  
本文档旨在克服Jabber浏览和代理信息这两个协议的弱点。其结果就是一个用于服务发现的标准追踪协议(通常缩写为“disco”,就和一些熟悉的协议,如简单对象访问协议(SOAP)\[5\]一样)。
+
本文档旨在克服Jabber Browsing和Agent Information这两个协议的弱点。其结果就是一个用于服务发现的标准追踪协议(通常缩写为“disco”,就和一些熟悉的协议,如 [http://www.w3.org/TR/SOAP/ SOAP] [[XEP-0030#附录G:备注|5]]一样)。
  
 
==需求==
 
==需求==
第85行: 第37行:
 
在作者的头脑中构思的服务发现协议要满足下面的需求:
 
在作者的头脑中构思的服务发现协议要满足下面的需求:
  
* 协议 '''必须''' 支持它所取代的协议(Jabber浏览和代理信息)之全部功能
+
* 协议 '''必须''' 支持它所取代的协议(Jabber Browsing 和 Agent Information)之全部功能
  
 
* 有三种关于一个实体的信息需要发现:
 
* 有三种关于一个实体的信息需要发现:
第91行: 第43行:
 
:# 它的基本身份(类型和/或目录)
 
:# 它的基本身份(类型和/或目录)
 
:# 它提供的特性和支持的协议
 
:# 它提供的特性和支持的协议
:# 与实体相关联的任何附加细节,无论它们是否能定址为JID
+
:# 与实体相关联的任何附加条目,无论它们是否能定址为JID
  
三种信息都 '''必须''' 支持,但前两种信息都与实体本身有关,而第三种信息与实体关联的细节有关;因此只需要两种不同的查询类型。
+
三种信息都 '''必须''' 支持,但前两种信息都与实体本身有关,而第三种信息与实体关联的条目有关;因此只需要两种不同的查询类型。
  
* 子细节信息的发现 '''必须''' 通过向它自己,而不是向父实体,发送单独的发现请求实现。(其后果之一是,要发现整个三种信息,需要多个请求/响应对,以“遍历整个信息树”)。
+
* 子条目信息的发现 '''必须''' 通过向它自己,而不是向父实体,发送单独的发现请求实现。(其后果之一是,要发现整个三种信息,需要多个请求/响应对,以“遍历整个信息树”)。
  
* 身份和特性表 '''必须''' 是柔性的。
+
* 身份和特性列表 '''必须''' 是柔性的。
  
 
* 协议本身 '''必须''' 是可扩展的。
 
* 协议本身 '''必须''' 是可扩展的。
第107行: 第59行:
 
一个发出请求的实体会想发现网络中另一个实体的信息。想得到的信息一般分为两种:
 
一个发出请求的实体会想发现网络中另一个实体的信息。想得到的信息一般分为两种:
  
# 对象实体的身份(identity)。在disco中,一个实体的身份被分成种类(category)(服务器、客户端、网关、目录等等)及其种类中的特殊类型(IM服务器、电话对处理的客户端、MSN网关对AIM网关、用户目录对聊天室目录等等)。这个信息帮助请求实体测定服务组或服务“桶”,以使实体最恰当地放置其中(例如,或许用个合适的图标把实体显示成GUI)。一个实体 __可以__ 有多个身份。当提供多个身份元素的时候,每个身份元素的名称属性 __应该__ 有相同的值。
+
# '''目标实体的身份'''(identity)。在disco中,一个实体的身份细分成种类(category)(服务器、客户端、网关、目录等等)及其种类中的特殊类型(IM服务器、电话对处理的客户端、MSN网关对AIM网关、用户目录对聊天室目录等等)。这个信息帮助请求实体测定服务组或服务“桶”,以使实体最恰当地放置其中(例如,或许用个合适的图标把实体显示成GUI)。一个实体 '''可以''' 有多个身份。当提供多个identity元素的时候,每个identity元素的 name 属性 '''应该''' 有相同的值。
# 目标实体提供的特性和支持的协议。这个信息帮助请求实体测定对目标实体可以做什么样的动作(注册、搜索、联合等等),实体支持什么样的协议,以及是否有感兴趣的特性类型(例如,为了特性协商的目的)。
+
# '''目标实体提供的特性和支持的协议'''。这个信息帮助请求实体测定对目标实体可以做什么样的动作(注册、搜索、联合等等),实体支持什么样的协议,以及是否有感兴趣的特性类型(例如,为了特性协商的目的)。
  
为了发现这样的信息,请求实体 '''必须''' 向目标实体的JID发送类型为“get”的IQ段,包含一个用命名空间'http://jabber.org/protocol/disco#info'标识的空的<query/>元素('to'的地址是 '''必需的''' , '''必须''' 包含有效的JID;<query>元素的'node'属性是 '''可选的''' ,本文中~~信息节点及细节节点~~一节对此有说明)。
+
为了发现这样的信息,请求实体 '''必须''' 向目标实体的JID发送类型为“get”的IQ节,包含一个用命名空间 'http://jabber.org/protocol/disco#info' 标识的空的 <query/> 元素('to'的地址是 '''必需的''' , '''必须''' 包含有效的JID;<query>元素的'node'属性是 '''可选的''' ,本文中 [[XEP-0030#信息节点|信息节点]] 和 [[XEP-0030#条目节点|条目节点]] 一节对此有说明)。
  
例1. 查询信息
+
'''例1. 查询信息'''
  
 
<source lang="xml">
 
<source lang="xml">
第123行: 第75行:
 
</source>
 
</source>
  
然后目标实体 __必须__ 返回一个IQ结果,或者返回一个错误(见文中[出错条件|XMPP文档列表/XMPP扩展/XEP-0030#出错条件])。结果 __必须__ 包含用命名空间'http://jabber.org/propocol/disco#info'标识的<query/>元素,元素中依次包含一个或多个<identity/>元素及一个或多个<feature/>元素。(注意:每个实体 __必须__ 至少有一个身份,每个实体 __必须__ 至少支持‘http://jabber.org/protocol/disco#info’特性;然而,并不要求一个实体一定返回一个结果,它也 __可以__ 返回一个错误,最可能的是<feature-not-implemented/>或<service-unavilable/>,虽然其他出错条件也是可以的)。每个<identity/>元素 __必须__ 拥有'category'和'type'属性,用来说明实体的种类。每个<feature/>元素 __必须__ 拥有一个'var'属性,它的值是协议的命名空间或是实体提供的其他特性。如果象本文中[XMPP注册事项|XMPP文档列表/XMPP扩展/XEP-0030#XMPP注册事项]一节说明的那样,种类/类型的值和特性值都在公共登记处注册了的话就更好了。
+
然后目标实体 '''必须''' 返回一个IQ结果,或者返回一个错误(见本文[[XEP-0030#错误条件|错误条件]])。结果 '''必须''' 包含用命名空间'http://jabber.org/propocol/disco#info'标识的<query/>元素,元素中依次包含一个或多个<identity/>元素及一个或多个<feature/>元素。(注意:每个实体 '''必须''' 至少有一个identity,每个实体 '''必须''' 至少支持 'http://jabber.org/protocol/disco#info' 特性;然而,并不要求一个实体一定返回一个结果,它也 '''可以''' 返回一个错误,最可能的是 <feature-not-implemented/> 或 <service-unavilable/>,虽然其他出错条件也是可以的)。
 +
 
 +
每个<identity/>元素 '''必须''' 拥有'category'和'type'属性,用来说明实体的种类, 而且可以 MAY 拥有一个 'name' 属性为这个实体指定一个自然语言的名字; 这个 <identity/> 元素也可以 MAY 拥有一个标准的 'xml:lang' 属性, 它使实体能返回本地化的结果,如果必要的话(即, <query/> 元素可以 MAY 包含多个 <identity/> 元素,使用相同的 category+type 但是不同的 'xml:lang' 值;无论如何 <query/> 元素不能 MUST NOT 以相同的 category+type+xml:lang 和不同的 'name' 值包含多个 <identity/> 元素,).
 +
 
 +
每个<feature/>元素 '''必须''' 拥有一个'var'属性,它的值是协议的命名空间或是实体提供的其他特性。
 +
 
 +
如果象本文中[[XEP-0030#XMPP登记事项|XMPP登记事项]]一节说明的那样,种类/类型的值和特性值都在公共登记处注册了的话就更好了。
  
例2. 信息请求的结果集
+
'''例2. 信息请求的结果集'''
  
 
<source lang="xml">
 
<source lang="xml">
第152行: 第110行:
 
</source>
 
</source>
  
如果指定目标实体的JID不存在,服务器或其他认证实体 __应该__ 返回一个<item-not-found/>错误,除非如果这么做会破坏在XMPP核心协议和{link:XMPP IM|http://tools.ietf.org/html/rfc3921}\[6\]中说明的隐私和安全事项,或是破坏本地隐私和安全策略(见文中[安全事项|XMPP文档列表/XMPP扩展/XEP-0030#安全事项])
+
如果指定目标实体的JID不存在,服务器或其他认证实体 '''应该''' 返回一个<item-not-found/>错误,除非如果这么做会破坏在[[RFC3920|XMPP Core]]和[[RFC3921|XMPP IM]] [[XEP-0030#附录G:备注|6]]中说明的隐私和安全事项,或是破坏本地隐私和安全策略(见本文[[XEP-0030#安全事项|安全事项]]):
  
例3. 目标实体不存在
+
'''例3. 目标实体不存在'''
  
 
<source lang="xml">
 
<source lang="xml">
第168行: 第126行:
 
</source>
 
</source>
  
如果隐私和安全事项或策略阻止服务器或其他授权实体返回<item-not-found/>错误,取而代之它 __应该__ 返回一个<service-unavailable/>错误。
+
如果隐私和安全事项或策略阻止服务器或其他授权实体返回<item-not-found/>错误,取而代之它 '''应该''' 返回一个<service-unavailable/>错误:
  
例4. 服务不可用
+
'''例4. 服务不可用'''
  
 
<source lang="xml">
 
<source lang="xml">
第184行: 第142行:
 
</source>
 
</source>
  
当一个实体向一个由服务器做宿主的裸JID(<account@domain.tld>)发送disco#info请求的时候,这个服务器 __必须__ 代表寄宿的帐号回应一个IQ错误或IQ结果。有关访问这些功能的重要规则,见本文的~~安全事项~~一节。特别地,为响应向一个没有节点的裸JID发出的disco#info请求,如果访问没被拒绝,服务器 __应该__ 为这个裸JID返回一个IQ结果,里面的主身份 __应该__ 有具有合适类型的“account”种类,类型在~~服务发现的身份~~注册中说明(最可能的是类型"registered")。注意:这使得那些已认证或信任的实体能发现帐号是否存在及帐号的类型(例如,在IM系统中,在把帐号加入联系列表之前检测它是否存在)。
+
当一个实体向一个由服务器做宿主的纯JID(<account@domain.tld>)发送disco#info请求的时候,这个服务器本身 '''必须''' 代表寄宿的帐号回应一个IQ错误或IQ结果。有关访问这些功能的重要规则,见本文的[[XEP-0030#安全事项|安全事项]]一节。特别地,为响应向一个没有节点的纯JID发出的disco#info请求,如果访问没被拒绝,服务器 '''应该''' 为这个纯JID返回一个IQ结果,里面的主 identity '''应该''' 有具有合适类型的“account”种类,类型在 Service Discovery Identities 注册中说明(最可能的是类型"registered")。注意:这使得那些已授权或被信任的实体能发现帐号帐号是否存在及帐号的类型(例如,在IM系统中,在把帐号加入联系人列表之前检测它是否存在)。
  
例5. 从裸JID那里请求信息
+
'''例5. 从纯JID那里请求信息'''
  
 
<source lang="xml">
 
<source lang="xml">
第199行: 第157行:
 
这里我们假定shakespeare.lit被capulet.com信任,而帐号<juliet@capulet.com>是个注册帐号:
 
这里我们假定shakespeare.lit被capulet.com信任,而帐号<juliet@capulet.com>是个注册帐号:
  
例 6. 服务器替裸JID答付
+
'''例 6. 服务器替纯JID应答'''
  
 
<source lang="xml">
 
<source lang="xml">
第214行: 第172行:
 
向关联实体发出的查询结果会不同,或能得到更详细的信息。一个例子是向一个特别的会议室而不是父实体的会议服务发出查询:
 
向关联实体发出的查询结果会不同,或能得到更详细的信息。一个例子是向一个特别的会议室而不是父实体的会议服务发出查询:
  
例7. 查询指定的会议室
+
'''例7. 查询指定的会议室'''
  
 
<source lang="xml">
 
<source lang="xml">
第248行: 第206行:
 
另一个例子是向一个带明确资源连接的IM用户发出查询:
 
另一个例子是向一个带明确资源连接的IM用户发出查询:
  
例 8. 查询连接资源的更详细的信息
+
'''例 8. 查询连接资源的更详细的信息'''
  
 
<source lang="xml">
 
<source lang="xml">
第273行: 第231行:
 
</source>
 
</source>
  
===信息节点==
+
===信息节点===
  
disco#查询 '''可以''' 直接发送到和一个JID关联的指定的节点标识符,虽然节点的主要作用是作为细节(Items)节点而不是信息(info)节点。
+
一个 disco#info 也查询可以 MAY 被定向到特定的关联到一个JID的节点标识符, 尽管节点的主要用途是成为条目节点 Items Nodes 而不是信息节点 info nodes:
  
9. 查询指定的JID和节点的组合
+
'''例子 9. 查询一个特定的JID和node的组合'''
  
 
<source lang="xml">
 
<source lang="xml">
第289行: 第247行:
 
</source>
 
</source>
  
如果请求包含'node'属性,那么响应也 __应该__ 映射指定的'node'属性,以保证请求和响应的一致。
+
如果请求包含 'node' 属性, 应答必须 MUST 镜像这个指定的 'node' 属性以确保请求和应答之间的相关性.
  
10. JID+node result
+
'''例子 10. JID+node结果'''
  
 
<source lang="xml">
 
<source lang="xml">
第307行: 第265行:
 
</source>
 
</source>
  
==发现与Jabber实体相关的细节==
+
 
 +
 
 +
==发现与Jabber实体相关的条目==
  
 
===基本协议===
 
===基本协议===
  
请求实体为了发现一个Jabber实体相关联的细节,它 __必须__ 向目标实体发送类型为"get"的IQ段,其中包含一个空的<query/>元素,受限命名空间为‘http://jabber.org/protocol/disco#items’:
+
请求实体为了发现一个Jabber实体相关联的条目,它 '''必须''' 向目标实体发送类型为"get"的IQ节,其中包含一个空的<query/>元素,受限命名空间为 'http://jabber.org/protocol/disco#items':
  
例11. 请求全部细节
+
'''例11. 请求全部条目'''
  
 
<source lang="xml">
 
<source lang="xml">
第324行: 第284行:
 
</source>
 
</source>
  
目标实体 '''必须''' 或者返回它的公开可用的细节列表,或者返回一个错误。细节列表 '''必须''' 是类型为"result"的IQ段,每个细节用<query/>的子元素<item/>来说明,受限命名空间是'http://jabber.org/protocol/disco#items'(子元素<item/> '''必须''' 用'jid'属性指定细节的JID, '''可以''' 用'name'属性说明细节的自然语言名):
+
目标实体 '''必须''' 返回它的公开可用的条目列表,或者返回一个错误。条目列表 '''必须''' 是类型为"result"的IQ段,每个条目用<query/>的子元素<item/>来说明,受限命名空间是 'http://jabber.org/protocol/disco#items' (子元素 <item/> '''必须''' 用'jid'属性指定条目的JID, '''可以''' 用'name'属性说明条目的自然语言名):
  
例12. 全部细节的结果集
+
'''例12. 所有条目的结果集'''
  
 
<source lang="xml">
 
<source lang="xml">
第356行: 第316行:
 
<item/>元素 '''必须不可''' 包含XML字符数据,并 '''应该''' 是空元素;当然它 '''可以''' 在其他命名空间中包含XML数据,如果一个Jabber实现不理解这些数据,则 '''必须''' 忽略它。
 
<item/>元素 '''必须不可''' 包含XML字符数据,并 '''应该''' 是空元素;当然它 '''可以''' 在其他命名空间中包含XML数据,如果一个Jabber实现不理解这些数据,则 '''必须''' 忽略它。
  
如果没有细节与实体相关联(或者这些细节并非公开可用的),目标实体必须向请求实体返回一个空的查询元素:
+
如果没有条目与实体相关联(或者这些条目并非公开可用的),目标实体必须向请求实体返回一个空的query元素:
  
例13. 空的结果集
+
'''例13. 空的结果集'''
  
 
<source lang="xml">
 
<source lang="xml">
第369行: 第329行:
 
</source>
 
</source>
  
就请求disco#info来说,当实体向寄生在一个服务器的裸JID(<account@domain.tld>)发送disco#items请求时,宿主服务器自身 __必须__ 代表寄生帐号回应。有关访问这个功能的重要准则,见本文档的安全事项一节。特别地,为响应发到一个不带节点的裸JID的disco#info请求,如果访问没被拒决,服务器 __应该__ 反回相关的细节,包括连接的和可用的资源:
+
就请求disco#info来说,当实体向寄生在一个服务器的纯JID(<account@domain.tld>)发送disco#items请求时,宿主服务器自身 '''必须''' 代表寄生帐号回应。有关访问这个功能的重要准则,见本文的[[XEP-0030#安全事项|安全事项]]一节。特别地,为响应发到一个不带节点的纯JID的disco#info请求,如果访问没被拒决,服务器 '''应该''' 返回相关的条目,包括适当的已连接或可用的资源:
  
例14. 从一个裸JID请求细节
+
'''例14. 从一个纯JID请求条目'''
  
 
<source lang="xml">
 
<source lang="xml">
第384行: 第344行:
 
在这儿我们假设shakespeare.lit被capulet.com信任,帐号<juliet@capulet.com>有两个可用的资源:
 
在这儿我们假设shakespeare.lit被capulet.com信任,帐号<juliet@capulet.com>有两个可用的资源:
  
例15. 服务器代表裸JID响应
+
'''例15. 服务器代表纯JID响应'''
  
 
<source lang="xml">
 
<source lang="xml">
第398行: 第358行:
 
</source>
 
</source>
  
===细节节点===
+
===条目节点===
  
与实体相关联的信息有可能不能写成JID地址的形式;这样的例子包括,储存在收件箱的离线消息(见[http://www.xmpp.org/extensions/xep-0013.html 柔性离线消息获取] [7])、有Jabber能力的博客中的条目、与一个客户和组件关联的XML-RPC服务、位于一个NNTP网关的新闻张贴、及由[http://www.xmpp.org/extensions/xep-0060.html 发布-订阅] [8]主办的标题等等。为处理这些细节,<item/>元素 '''可以''' 有个 '''可选的''' 'node'属性来补充这个 '''必须的''' 'jid'属性。
+
与实体相关联的条目有可能不能写成JID地址的形式;这样的例子包括,储存在收件箱的离线消息(见[http://www.xmpp.org/extensions/xep-0013.html 柔性离线消息获取] [[XEP-0030#附录G:备注|7]])、有Jabber能力的博客中的条目、与一个客户或组件关联的XML-RPC服务、在一个在线交易系统中的可用条目 (例如, 一个目录或拍卖)、位于一个NNTP网关的新闻贴、及由[[XEP-0060|发布-订阅]] [[XEP-0030#附录G:备注|8]]组件 主办的主题等等。为处理这些条目,<item/>元素 '''可以''' 有个 '''可选的''' 'node'属性来补充这个 '''必须的''' 'jid'属性。
  
节点的属性值或许有或许没有语义上的含义;从服务发现的观点来看,一个节点只不过是个与实体相联系的某种东西。为了发现节点更多的东西,请求实体 '''必须''' 在指定节点的时候查询实体的JID。如果'node'属性的值有语义上的含义,则这个含义是由使用的协议或应用提供的,而不是由服务发现协议决定的。'''不应该''' 包含节点属性,除非需要提供,或者要发现信息的实体不能直接写成JID地址的形式(就是说,如果相关的条目能写成一个JID就不要包含一个节点)。'node'属性的指 '''必须不能''' 为空。
+
节点的属性值可以有或没有语义上的含义;从服务发现的观点来看,一个节点只不过是个与实体相联系的某种东西。为了发现节点更多的东西,请求实体 '''必须''' 在查询实体的JID的时候指定节点。如果'node'属性的值有语义上的含义,意味着这个含义是由"使用的协议"或应用提供的,而不是由服务发现协议决定的。'''不应该''' 包含节点属性,除非需要提供,或者要发现信息的实体不能直接写成JID地址的形式(就是说,如果相关的条目能写成一个JID就不要包含一个节点)。'node'属性的值 '''必须不能''' 为空。
  
在下面的例子中,用户从一个在线目录服务中请求所有可用的细节:
+
在下面的例子中,用户从一个在线目录服务中请求所有可用的条目:
  
例16. 请求节点
+
'''例16. 请求节点'''
  
 
<source lang="xml">
 
<source lang="xml">
第417行: 第377行:
 
</source>
 
</source>
  
如果有与目标实体相关的细节单它们不能写成JID地址,那么服务 '''应该''' 返回一个节点列表(每个<item/>元素 '''必须''' 有一个'jid'属性, '''应该''' 有个'node'属性, '''可以''' 有个'name'属性):
+
如果有与目标实体相关的条目但它们不能写成JID地址,那么服务 '''应该''' 返回一个节点列表(每个<item/>元素 '''必须''' 有一个'jid'属性, '''应该''' 有个'node'属性, '''可以''' 有个'name'属性):
  
例17. 服务反回节点
+
'''例17. 服务返回节点'''
  
 
<source lang="xml">
 
<source lang="xml">
第440行: 第400行:
 
</source>
 
</source>
  
在返回上面的查询时,也许有更深层的节点与"第一级"节点相关联(比如,那些有相关细节的种类节点)。请求实体可以通过向这个JID发送请求,并在请求中说明感兴趣的节点,来进一步查询节点。
+
在返回上面的查询时,也许有更多的节点与"第一级"节点相关联(比如,节点可能是一个类别,有下级条目)。请求实体可以通过向这个JID发送请求,并在请求中说明感兴趣的节点,来进一步查询节点。
  
例18. 请求更深层的节点
+
'''例18. 请求更多的节点'''
  
 
<source lang="xml">
 
<source lang="xml">
第456行: 第416行:
 
然后服务返回与“父”节点相关的更深层的节点。在下面的例子中,服务本身将返回的节点按字母顺序排序,不过这种结构是实现的问题而不是协议的要求。
 
然后服务返回与“父”节点相关的更深层的节点。在下面的例子中,服务本身将返回的节点按字母顺序排序,不过这种结构是实现的问题而不是协议的要求。
  
例19. 服务返回更深层的节点
+
'''例19. 服务返回更深层的节点'''
  
 
<source lang="xml">
 
<source lang="xml">
第482行: 第442行:
 
如果想要,请求实体可以继续查询更深层的节点:
 
如果想要,请求实体可以继续查询更深层的节点:
  
例20. 请求更深层节点
+
'''例20. 请求更深层节点'''
  
 
<source lang="xml">
 
<source lang="xml">
第494行: 第454行:
 
</source>
 
</source>
  
例21. 服务返回更多的节点
+
'''例21. 服务返回更多的节点'''
  
 
<source lang="xml">
 
<source lang="xml">
第515行: 第475行:
 
===节点层次结构===
 
===节点层次结构===
  
前面的例子显示了节点的层次结构,里面的有些节点是分支(也即包含更深层的节点),有些节点是叶子(即不包含更深层的节点)。 '''应该''' 用"分层的"的种类来区分这些节点,“分支”和“叶子”类型详尽地列出了这个种类中的类型。
+
前面的例子显示了节点的层次结构,里面的有些节点是分支(也即包含更深层的节点),有些节点是叶子(即不包含更深层的节点)。 '''应该''' 用"hierarchy"这个category来区分这些节点,“分支”和“叶子”表示这个种类category的具体类型type。
  
如果使用了分层种类,层次结构中的每个节点 '''必须''' 区分为要么是分支要么是叶子;然而,因为一个节点 '''可以''' 有多个身份,所以任一节点也 '''可以''' 有一个除了“层次/分支”或“层次/叶子”结构外的身份。
+
如果使用了分层种类,层次结构中的每个节点 '''必须''' 标识为要么是分支要么是叶子;然而,因为一个节点 '''可以''' 有多个身份,所以任一节点也 '''可以''' 有一个除了“层次/分支”或“层次/叶子”结构外的身份。
  
 
因此,上面显示的例子中,一个向"music/D"的disco#info请求会产生<identity category='hierarchy' type='branch'/>,而向"<music/D/dowland-firstbooke>"节点发出的请求会产生<identity category='hierarchy' type='leaf'/>(每个节点会产生恰当的附加身份)。
 
因此,上面显示的例子中,一个向"music/D"的disco#info请求会产生<identity category='hierarchy' type='branch'/>,而向"<music/D/dowland-firstbooke>"节点发出的请求会产生<identity category='hierarchy' type='leaf'/>(每个节点会产生恰当的附加身份)。
  
===实体和其细节的关系===
+
===实体和其条目的关系===
  
本节要说明的是一个实体和它的相关细节更详细的关系。
+
本节要说明的是一个实体和它的相关条目之间更详细的关系。
  
一般情况下,由一个实体在disco#items结果中返回的细节 __必须__ 是与实体有隶属关系的项\--或者是实体直接控制的细节的本身(比如,实体拥有的发布-订阅节点),或者实体至少能以Jabber网络中规范的方式提供或确保这样的细节(例如,群聊房间直接由一个多用户聊天服务来主持,还有网关提供的对IRC通道的访问等)。
+
一般情况下,由一个实体在disco#items结果中返回的条目 '''必须''' 是与实体有隶属关系的条目 --或者是实体直接控制条目本身(比如,实体拥有的Publish-Subscribe节点),或者实体至少能以Jabber网络中规范的方式提供或确保这些条目(例如,群聊房间直接寄宿于一个多用户聊天服务或一个通过网关提供访问的IRC频道)。
  
 
这样的关系并不限制所属实体的地址与相关实体地址间的关系。特别地,下面任何一种情况都是非常合适的:
 
这样的关系并不限制所属实体的地址与相关实体地址间的关系。特别地,下面任何一种情况都是非常合适的:
  
# 查询一个实体(JID1)的细节时,接收到可定址为JID的细节列表;每个相关项都有自己的JID,这些JID都与JID1不相同。
+
# 查询一个实体(JID1)的条目时,接收到可定址为JID的条目列表;每个相关条目都有自己的JID,但这些JID都与JID1不相同。
# 查询一个实体(JID1)的细节时,接收到不可定址为JID的细节列表;每个相关项有各自的JID+Node,其中JID与JID1相同但每个NodeId都是唯一的。
+
# 查询一个实体(JID1)的条目时,接收到不可定址为JID的条目列表;每个相关条目有各自的JID+Node,其中JID与JID1相同但每个NodeId都是唯一的。
# 查询一个实体(JID1+NodeID1)的细节时,接收到可定址为JID的细节列表;每个相关项有自己的JID,但没有JID与JID1相同。
+
# 查询一个实体(JID1+NodeID1)的条目时,接收到可定址为JID的条目列表;每个相关条目有自己的JID,但没有JID与JID1相同。
# 查询一个实体(JID1+NodeId1)的细节时,接收到不能定址为JID的细节列表;每个相关项有自己的JID+node,但是没有JID+node与JID1+NodeID1相同,并且每个NodeID都在相关JID的上下文中都是唯一的。
+
# 查询一个实体(JID1+NodeId1)的条目时,接收到不能定址为JID的细节列表;每个相关条目有自己的JID+node,但是没有JID+node与JID1+NodeID1相同,并且每个NodeID都在相关JID的上下文中都是唯一的。
  
另外,返回的结果也 __可以__ 是混合型的,这样查询一个JID或JID+node会产生(1)定址为JID的项和(2)定址为JID+node这两种的组合。
+
另外,返回的结果也 '''可以''' 是混合型的,这样查询一个JID或JID+node会产生(1)定址为JID的项和(2)定址为JID+node这两种的组合。
  
考虑一下实体的这种情况,它拥有多个发布-订阅节点\--例如,一个拥有多个音乐演奏家节点的人。下面的例子演示了disco#items查询及其结果会是什么样子(用了在{link:用户心情|http://www.xmpp.org/extensions/xep-0118.html}中定义的协议):
+
考虑一下实体的这种情况,它拥有多个 发布-订阅 节点 --例如,一个人拥有多个音乐演奏家节点。下面的例子演示了disco#items查询及其结果会是什么样子(使用了在[http://www.xmpp.org/extensions/xep-0118.html User Tune] [[XEP-0030#附录G:备注|9]]中定义的协议):
  
例22. 用户请求有关实体的心情
+
'''例22. 用户请求有关实体的音乐'''
  
 
<source lang="xml">
 
<source lang="xml">
第550行: 第510行:
 
</source>
 
</source>
  
被查询的实体现在返回一个它控制的发布-订阅节点的列表,每个节点都由不同的发布订阅服务主持:
+
被查询的实体现在返回一个它控制的 发布-订阅publish-subscribe 节点的列表,每个节点寄宿于不同的发布订阅 pubsub 服务:
  
The queried entity now returns a list of publish-subscribe nodes over which it has control, each of which is hosted on a different pubsub service:
+
'''例23. 实体返回多项条目'''
 
+
例23. 实体返回多项细节
+
  
 
<source lang="xml">
 
<source lang="xml">
第574行: 第532行:
 
</source>
 
</source>
  
==发表可用的细节==
+
==发布可用的条目==
  
在XMPP IM中定义的服务器处理规则要求,如果IQ存取指令的'to'属性是<user@host>这样的形式的话,服务器应代表用户回应请求。这种功能目前已得到应用,这样用户就能“发布”信息(不如,在{link:vcard-temp|http://www.xmpp.org/extensions/xep-0054.html}中说明的vCard),这使得其他实体得到这些信息成为可能,即使这个用户不在线。这里定义的服务发现规范就建立在这个想法之上,使用户能够向服务器发布他的一些服务发现信息,服务器将把这些信息做持久化保存,当其他实体以用户的“裸JID”(user@host),或单独或与一个特殊节点组合来请求信息的时候,服务器将其返回。
+
这个特性已经被移到定义 XMPP 发行-订阅 技术的 [[XEP-0060]] 中去了.
 
+
在即时通服务器中实现服务发现 __应该__ 允许用户按这种方式发布细节,虽然服务发现规范并不要求这么做。为了发现他或她的服务器是否支持这种发布功能,用户 '''应该''' 向服务器发送一个disco#info请求:
+
 
+
例24. 用户向服务器发送disco#info请求
+
 
+
<source lang="xml">
+
<iq from='kinglear@shakespeare.lit'
+
    id='pubinfo'
+
    to='shakespeare.lit'
+
    type='get'>
+
  <query xmlns='http://jabber.org/protocol/disco#info'/>
+
</iq>
+
</source>
+
 
+
如果服务器支持服务发现的发布,并且服务器想要向用户披露这个事实,它 __必须__ 在响应中包含特性'http://jabber.org/protocol/disco#publish'。
+
 
+
例25. 服务器用身份及特性信息响应请求
+
 
+
<source lang="xml">
+
<iq from='shakespeare.lit'
+
    id='pubinfo'
+
    to='kinglear@shakespeare.lit'
+
    type='result'>
+
  <query xmlns='http://jabber.org/protocol/disco#info'>
+
    <identity category='server' type='im'/>
+
    ...
+
    <feature var='http://jabber.org/protocol/disco#publish'/>
+
    ...
+
  </query>
+
</iq>
+
</source>
+
 
+
为了发布细节,实体将一个IQ-set会话发给服务器,服务器代表实体负责响应请求。父查询的每个<item/>子元素 '''必须''' 拥有下面的属性:
+
 
+
* action -- 说明向细节施加的动作
+
 
+
* jid -- 说明细节“属主 或位置的Jabber ID
+
 
+
<item/>元素也 '''可以''' 有下面的属性:
+
 
+
* name -- 说明细节的自然语言名
+
 
+
* node -- 说明与细节“属主”或位置的JID相关联的特殊节点
+
 
+
'action'属性允许的值是“update”和“remove”。如果动作是“update”,服务器 '''必须''' 新建一个新的实体(如果节点和jid的组合不存在的话),或者改写现有的实体。如果动作是“remove”, '''必须''' 将细节从持久化保存中去除。
+
 
+
下面的例子演示了用户向一个知名的(但却是假设的)服务发现节点发布他的孩子的列表。
+
 
+
例26. 发布细节
+
 
+
<source lang="xml">
+
<iq from='kinglear@shakespeare.lit'
+
    id='publish1'
+
    type='set'>
+
  <query xmlns='http://jabber.org/protocol/disco#items'
+
        node='jabber:iq:kids'>
+
    <item action='update'
+
          jid='cordelia@shakespeare.lit'
+
          name='Cordelia'/>
+
    <item action='update'
+
          jid='goneril@shakespeare.lit'
+
          name='Goneril'/>
+
    <item action='update'
+
          jid='regan@shakespeare.lit'
+
          name='Regan'/>
+
  </query>
+
</iq>
+
</source>
+
 
+
例27. 服务以成功响应
+
 
+
<source lang="xml">
+
<iq id='publish1'
+
    to='kinglear@shakespeare.lit'
+
    type='result'/>
+
</source>
+
 
+
之后如果对“jid='kinglear@shakespeare.lib”和"node='jabber:iq:kids"查询就会产生上面显示的列表(没有'action'属性)。
+
 
+
如果服务器或服务不支持持久化保存,它 __必须__ 对IQ-set请求响应<feature-not-implemented/>错误。
+
 
+
例28. 持久化保存不可用
+
 
+
<source lang="xml">
+
<iq id='publish1'
+
    to='kinglear@shakespeare.lit'
+
    type='error'>
+
  <query xmlns='http://jabber.org/protocol/disco#items'
+
        node='jabber:iq:kids'>
+
    <item action='update'
+
          jid='cordelia@shakespeare.lit'
+
          name='Cordelia'/>
+
    <item action='update'
+
          jid='goneril@shakespeare.lit'
+
          name='Goneril'/>
+
    <item action='update'
+
          jid='regan@shakespeare.lit'
+
          name='Regan'/>
+
  </query>
+
  <error code='501' type='cancel'>
+
    <feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
+
  </error>
+
</iq>
+
</source>
+
  
==实现时的注意事项==
+
==实现注意事项==
  
 
===信息请求数===
 
===信息请求数===
  
当请求应用是一个客户端的时候,在得到用户取得花名册后,它也许想得到所有联系人的服务发现信息,并接收用户花名册中联系人的在线信息。不幸的是,用户的花名册可能很长,结果登录后会向外发出大量的disco#info查询和接收进来大量的disco#info响应。基于升级和带宽利用的原因,并不希望有这种“发现洪流”,因此,客户端应用 __应该__ {link:实体能力|http://www.xmpp.org/extensions/xep-0115.html}\[11\]来确定它们接收到的在线信息的那些实体的能力,而 __不应该__ 向这些实体发送disco#info请求。
+
当发出请求的应用是一个客户端的时候,在用户收到好友名册并收到名册中所有联系人的出席信息(例如, 展示可用)后,它也许想得到所有联系人的服务发现信息。不幸的是,用户的花名册可能很长,结果登录后会向外发出大量的disco#info查询和接收进来大量的disco#info响应。基于可扩展性和带宽利用的原因,并不希望有这种“发现洪流”,因此,客户端应用 '''应该''' [http://www.xmpp.org/extensions/xep-0115.html 实体能力] [[XEP-0030#附录G:备注|10]]来确定它们接收到了出席信息的那些实体的能力,而 '''不应该''' 向这些实体发送disco#info请求。
  
===细节请求数===
+
===请求的条目数===
  
为了获取实体及相关细节的完整信息,发出请求的应用程序需要“遍历”细节树。很自然,这会产生大量的请求和响应。如果细节列表很长的话(比如,超过20条),发出请求的应用程序 __不应该__ 对所有的细节项连续发送请求。日常需要维护大量细节的那些实体(如IRC网关货NNTP服务) __应该__ 将节点组织成层次结构,并且/或者通过象{link:Jabber搜索|http://www.xmpp.org/extensions/xep-0055.html}\[12\]之类的协议,提供更健壮的搜索能力; __不应该__ 通过服务发现返回极其巨大的结果集。
+
为了获取实体及相关条目的完整信息,发出请求的应用程序需要“遍历”细节树。很自然,这会产生大量的请求和响应。如果条目列表很长的话(比如,超过20条),发出请求的应用程序接下来 '''不应该''' 对所有的条目发送请求。日常需要维护大量条目的那些实体(如IRC网关或NNTP服务) '''应该''' 将节点组织成层次结构,并且/或者通过像 [http://www.xmpp.org/extensions/xep-0055.html Jabber Search] [[XEP-0030#附录G:备注|11]]之类的协议,提供更健壮的搜索能力; '''不应该''' 通过服务发现返回极其巨大的结果集。
  
===响应连续性===
+
===响应一致性===
  
本文档推荐但并不要求响应实体必须对来自不同的请求实体的相同的请求返回一样的结果(比如,一个实体基于对请求实体的信任度或是已知能力的不同,可能返回不同的细节或特性列表)。然而,响应实体 __应该__ 对发送到相同的JID+节点组合的所有disco#info请求返回相同的<identity/>元素。
+
本文档推荐但并不要求响应实体对来自不同的请求实体的相同的请求返回一样的结果(比如,一个实体基于对请求实体的信任度或是已知能力的不同,可能返回不同的细节或特性列表)。然而,响应实体 '''应该''' 对发送到相同的 JID+node 组合的所有disco#info请求返回相同的<identity/>元素(category+type) 。
  
==出错条件==
+
==错误条件==
  
如果特定的实体(JID或JID+节点)不支持disco命名空间,拒绝对特定的请求实体或任何请求实体返回disco结果,它 '''应该''' 返回适当的错误信息(象<service-unavailable/>,<forbidden/>,或<not-allowed/>等等)。示例如下:
+
如果特定的实体(JID或JID+node)不支持disco命名空间,拒绝对特定的请求实体或任何请求实体返回disco结果,它 '''应该''' 分别返回适当的错误信息(象<service-unavailable/>,<forbidden/>,或<not-allowed/>等等)。示例如下:
  
例29. JID+节点错误
+
'''例24. JID+node错误'''
  
 
<source lang="xml">
 
<source lang="xml">
第717行: 第571行:
 
根据应用的不同,也可以有其他的错误条件。
 
根据应用的不同,也可以有其他的错误条件。
  
下表总结了通用的错误条件,它们在服务发现上下文中可能有特殊的含义(关于错误条件的格式和语义的信息,见{link:错误条件映射|http://www.xmpp.org/extensions/xep-0086.html}\[13\])。
+
下表总结了常见的错误条件,它们在服务发现Service Discovery的上下文中可能有特殊的含义(关于错误条件的语法和语义的信息,见[http://xmpp.org/extensions/xep-0086.html 错误条件映射]  [[XEP-0030#附录G:备注|12]])。
  
表1: 错误条件
+
'''表1: 错误条件'''
  
 
{|border="1" cellspacing="0"  
 
{|border="1" cellspacing="0"  
 
!条件 !! 原因
 
!条件 !! 原因
 
|-
 
|-
|<feature-not-implemented/> || 发送方试图发布细节,但服务器不支持发布可用细节这个特性。
+
|<item-not-found/> || 指定目标实体的JID或JID+NodeID并不存在,并且依据隐私及安全事项和策略,这一事实可以暴露。
|-
+
|<item-not-found/> || 由JID或JID+NodeId指定的目标实体并不存在,并且这一事实只可依据隐私及安全事项和策略来暴露。
+
 
|-
 
|-
 
|<service-unavailable/> || 目标实体不支持这一协议,或者指定的目标实体并不存在,但这一事实因为隐私及安全事项不能暴露。
 
|<service-unavailable/> || 目标实体不支持这一协议,或者指定的目标实体并不存在,但这一事实因为隐私及安全事项不能暴露。
 
|}
 
|}
  
其他在XMPP核心中说明的错误条件也 __可以__ 返回(<forbidden/>,<not-allowed/>,<not-authorized/>等等),包括应用专有的错误条件。
+
其他在'''XMPP Core'''中说明的错误条件也 '''可以''' 返回(<forbidden/>,<not-allowed/>,<not-authorized/>等等),包括应用专有的错误条件。
  
正象上面说明的那样,如果一个实体没有相关的细节,它 __必须__ 返回一个空的<query/>元素(而不是一个错误)来响应disco#items请求。
+
正象上面说明的那样,如果一个实体没有相关的子条目,它 '''必须''' 返回一个空的<query/>元素(而不是一个错误)来响应disco#items请求。
  
 
==安全事项==
 
==安全事项==
  
当实体暴露(通过disco#info响应)它支持的特定的协议或特性的时候,某些攻击会更容易发生;然而,一般来说,服务发现不会引入新的攻击点,因为恶意实体会通过发送对这些协议的特定的请求而不是服务发现请求,来发现响应实体支持这些协议和特性。
+
当实体暴露(通过disco#info响应)它支持的特定的协议或特性的时候,某些攻击会更容易发生;然而,一般来说,服务发现不会引入新的漏洞,因为恶意实体会通过发送对这些协议的特定的请求而不是服务发现请求,来发现响应实体支持哪些协议和特性。
  
 
当响应实体应答从不同的请求实体接收到的服务发现请求的时候,它没有义务返回相同的服务发现响应。 它 '''可以''' 在响应前执行授权检测,以决定怎样(或是否)响应。
 
当响应实体应答从不同的请求实体接收到的服务发现请求的时候,它没有义务返回相同的服务发现响应。 它 '''可以''' 在响应前执行授权检测,以决定怎样(或是否)响应。
  
服务器 '''必须''' 小心地控制对任何能发生目录收获攻击或泻露已连接或可用资源的功能的访问,这些功能由服务器对发送到寄宿其中的裸JID(地址型如account@domain.tld)的disco#info和disco#items请求的响应组成,因为服务器要代表这个帐户响应这样的请求。处理发送到裸JID的服务发现请求时应用如下规则:
+
服务器 '''必须''' 小心地控制对任何可能导致目录获取攻击或泻露已连接或可用资源的功能的访问,这些功能由服务器对发送到寄宿其中的纯JID(地址型如account@domain.tld)的disco#info和disco#items请求的响应组成,因为服务器要代表这个帐户响应这样的请求。处理发送到纯JID的服务发现请求时应用如下规则:
 
+
1. 为了响应disco#info请求,如果下列条件为真,服务器 '''必须'' 返回<service-unavailable/>错误:
+
 
+
* 目标实体不存在(无论请求指定的是否是一个节点)
+
  
* 请求实体未经授权从目标实体接收在线信息(也即,在线订阅的类型是"both"或"from"),或者请求实体不被信任(例如,在一个信任网络中的另一个服务器)。
+
1. 为了响应disco#info请求,如果下列条件之一为真,服务器 '''必须''' 返回<service-unavailable/>错误:
  
2. 为了响应disco#items请求,服务器 '''必须''' 返回一个空结果集如果:
+
# 目标实体不存在(无论请求指定的是否是一个节点)
 +
# 请求实体未经授权从目标实体接收出席信息(也即,出席信息订阅的类型是"both"或"from"),或者请求实体不被信任(例如,在一个信任网络中的另一个服务器)。
  
* 目标实体不存在(无论请求指定的是否是一个节点)
+
2. 为了响应disco#items请求,服务器 '''必须''' 返回一个空结果集,如果:
  
* 请求没有指定节点,唯一的细节是可用的资源(象在RFC3921中定义的那样),并且请求实体未经授权从目标实体接收在线信息(也即,在线订阅的类型是"both"或"from"),或者请求实体不被信任(例如,在一个信任网络中的另一个服务器)\[14\]
+
# 目标实体不存在(无论请求指定的是否是一个节点)
 +
# 请求没有指定节点,唯一的条目是可用的资源(象在'''RFC3921'''中定义的那样),并且请求实体未经授权从目标实体接收出席信息(也即,出席信息订阅的类型是"both"或"from"),或者请求实体不被信任(例如,在一个信任网络中的另一个服务器)[[XEP-0030#附录G:备注|13]]
  
 
==IANA事项==
 
==IANA事项==
  
本文档与[http://www.iana.org/ 互联网分配数字授权] [15]无关。
+
本文档与[http://www.iana.org/ 互联网编号分配授权机构] [[XEP-0030#附录G:备注|14]]无关。
  
==XMPP注册事项==
+
==XMPP登记事项==
  
===协议命名空间===
+
===协议名字空间===
  
[http://www.xmpp.org/registrar/ XMPP注册处] [16]在它的协议命名空间注册项中包含了'http://jabber.org/protocol/disco#info'和'http://jabber.org/protocol/disco#items'
+
[http://www.xmpp.org/registrar/ XMPP Registrar] [[XEP-0030#附录G:备注|15]]在它的协议名字空间注册项中包含了 'http://jabber.org/protocol/disco#info' 和 'http://jabber.org/protocol/disco#items' 名字空间
  
===注册===
+
===登记处===
  
====身份种类及类型注册====
+
====身份种类及类型登记====
  
XMPP注册处维护着命名空间'http://jabber.org/protocol/disco#info'里<identity/>元素的属性的'category'和'type'的注册值;见<{link:http://www.xmpp.org/registrar/disco-categories.html}>
+
XMPP登记处 XMPP Registrar 维护着命名空间'http://jabber.org/protocol/disco#info'里<identity/>元素的属性的'category'和'type'的注册值;见<[http://www.xmpp.org/registrar/disco-categories.html http://www.xmpp.org/registrar/disco-categories.html]>
  
 
=====过程=====
 
=====过程=====
  
为了向注册项提交新值,注册人必须按如下的形式定义XML段,然后将其包含在相关的XMPP扩展协议中或是发送到<registrar@xmpp.org>:
+
为了向注册项提交新值,注册人将按如下的形式定义XML段,然后将其包含在相关的XMPP扩展协议中或是发送邮件到<registrar@xmpp.org>:
  
 
<source lang="xml">
 
<source lang="xml">
第821行: 第671行:
 
====特性注册====
 
====特性注册====
  
XMPP注册处维护着以名字空间'http://jabber.org/protocol/disco#info'命名的一个属性注册项,用于元素<feature/>的属性‘var’的值;见<[http://www.xmpp.org/registrar/disco-features.html]>。
+
XMPP登记处维护着一个特性注册项,用于遵循 'http://jabber.org/protocol/disco#info' 名字空间的 <feature/> 元素的 'var' 属性的值;见<[http://www.xmpp.org/registrar/disco-features.html http://xmpp.org/registrar/disco-features.html>]>。
  
 
=====过程=====
 
=====过程=====
  
为了向注册项提交新值,注册人必须按如下格式定义一个XML片段,将它包含在相关的XMPP扩展协议中,或者发到<registrar@xmpp.org>:
+
为了向注册表提交新值,注册人必须按如下格式定义一个XML片段,将它包含在相关的XMPP扩展协议中,或者发到<registrar@xmpp.org>:
  
 
<source lang="xml">
 
<source lang="xml">
第835行: 第685行:
  
 
注册人可一次注册一个以上的特性,每个特性包含在独立的<feature>元素中。
 
注册人可一次注册一个以上的特性,每个特性包含在独立的<feature>元素中。
 
=====初始提交=====
 
 
本文档定义了一个“publish”特性,它不与上面列出的任何协议命名空间相关;这个特性注册项的提交形式如下:
 
 
<source lang="xml">
 
<feature var='http://jabber.org/protocol/disco#publish'>
 
  <desc>the service discovery "publish" feature</desc>
 
  <doc>XEP-0030</doc>
 
</feature>
 
</source>
 
  
 
====知名节点====
 
====知名节点====
  
一个正在使用的协议可以指定一个或以上的服务发现节点,这些节点在协议上下文中有特殊的、恰当定义的含义。为了全局性地跨所有Jabber协议保留这些节点名字,XMPP注册处在<{link:http://www.xmpp.org/registrar/nodes.html}>维护着一个知名服务发现节点的注册。
+
一个正在使用的协议可以指定一个或以上的服务发现节点,这些节点在协议上下文中有特殊的、恰当定义的含义。为了全局性地跨所有Jabber协议保留这些节点名字,XMPP登记处在<[http://www.xmpp.org/registrar/nodes.html http://www.xmpp.org/registrar/nodes.html]>维护着一个知名服务发现节点的注册。
  
 
=====过程=====
 
=====过程=====
  
为了向注册处提交新值,注册人必须按如下格式定义一个XML片段,然后将它包含在相关的XMPP扩展协议中,或者发到<registrar@xmpp.org>:
+
为了向登记处提交新值,注册人必须按如下格式定义一个XML片段,然后将它包含在相关的XMPP扩展协议中,或者发邮件到<registrar@xmpp.org>:
  
 
<source lang="xml">
 
<source lang="xml">
第867行: 第706行:
 
===URI查询类型===
 
===URI查询类型===
  
作为由{link:XMPP URI 查询组件|http://www.xmpp.org/extensions/xep-0147.html}\[17\]授权的机构,XMPP注册处维护着一个用在XMPP URIs中的查询和键-值对的注册(见<{link:http://www.xmpp.org/registrar/querytypes.html}>)。
+
作为由[http://www.xmpp.org/extensions/xep-0147.html XMPP URI Query Components] [[XEP-0030#附录G:备注|16]]授权的机构,XMPP登记处维护着一个用于 XMPP URIs 的查询和键-值对的注册项(见<[http://www.xmpp.org/registrar/querytypes.html http://www.xmpp.org/registrar/querytypes.html]>)。
  
在这里定义了用于服务发现交互的查询类型“disco”,它有三个键:(1)"node"(查询可选节点),(2)"request"(带“info”值来取回服务发现信息,带“items”值取回服务发现细节),(3)“type”(带值“get”用于IQ取值,“set”用于IQ设置)。
+
在这里定义了用于服务发现交互的查询类型“disco”,它有三个键:(1)"node"(查询的可选节点),(2)"request"(带“info”值来取回服务发现信息,带“items”值取回服务发现条目),(3)“type”(带值“get”用于IQ取值,“set”用于IQ设置)。
  
例30. 服务发现信息请求:IRI/URI
+
'''例25. 服务发现信息请求:IRI/URI'''
  
 
<source lang="xml">
 
<source lang="xml">
第877行: 第716行:
 
</source>
 
</source>
  
例31. 服务发现信息请求:结果段
+
'''例26. 服务发现信息请求:结果节'''
  
 
<source lang="xml">
 
<source lang="xml">
第885行: 第724行:
 
</source>
 
</source>
  
例32. 服务发现细节请求: IRI/URI
+
'''例27. 服务发现条目请求: IRI/URI'''
  
 
<source lang="xml">
 
<source lang="xml">
第891行: 第730行:
 
</source>
 
</source>
  
例33. 服务发现细节请求:结果段
+
'''例28. 服务发现条目请求:结果节'''
  
 
<source lang="xml">
 
<source lang="xml">
第944行: 第783行:
 
</source>
 
</source>
  
==XML方案==
+
==XML架构==
  
 
===disco#info===
 
===disco#info===
第1,061行: 第900行:
 
</source>
 
</source>
  
'''作者介绍'''
+
==作者备注==
 +
 
 +
Peter Millard, 本文的一个合著者,从版本0.1到版本2.2, 死于2006年4月26日.
 +
 
 +
==附录==
 +
===附录A:文档信息===
 +
 
 +
系列:[http://xmpp.org/extensions/ XEP]
 +
 
 +
序号:0030
 +
 
 +
发布者:[http://xmpp.org/xsf/ XMPP标准基金会]
 +
 
 +
状态:[http://www.xmpp.org/extensions/xep-0001.html#states-Final 终结版]
 +
 
 +
类型:[http://www.xmpp.org/extensions/xep-0001.html#types-Standards%20Track 标准跟踪]
 +
 
 +
版本:2.4
 +
 
 +
最后更新:2008-06-06
 +
 
 +
批准机构:[http://xmpp.org/council/ XMPP理事会]
 +
 
 +
依赖标准:[[RFC3920|XMPP Core]]
 +
 
 +
替代标准:XEP-0011, XEP-0094
 +
 
 +
被替代标准:无
 +
 
 +
缩略名:disco
 +
 
 +
disco#info名字空间的XML架构(Schema)[http://www.xmpp.org/schemas/disco-info.xsd]
 +
 
 +
disco#items名字空间的XML方案(Schema)[http://www.xmpp.org/schemas/disco-items.xsd]
 +
 
 +
注册项: <http://xmpp.org/registrar/disco.html>
 +
 
 +
原文控制: [http://svn.xmpp.org:18080/browse/XMPP/trunk/extensions/xep-0030.xml HTML] [http://svn.xmpp.org:18080//changelog/~rss/XMPP/trunk/extensions/xep-0030.xml/rss.xml RSS]
 +
 
 +
本文的其它格式: [http://xmpp.org/extensions/xep-0030.xml XML] [http://xmpp.org/extensions/xep-0030.pdf PDF]
 +
 
 +
===附录B:作者信息===
 +
 
 +
'''Joe Hildebrand'''
 +
 
 +
Email: [mailto:jhildebr@cisco.com jhildebr@cisco.com]
 +
 
 +
JabberID: hildjj@jabber.org
 +
 
 +
'''Peter Millard'''
 +
 
 +
见 [[XEP-0030#作者备注|作者备注]]
 +
 
 +
'''Ryan Eatmon'''
 +
 
 +
Email: [mailto:reatmon@jabber.org reatmon@jabber.org]
 +
 
 +
JabberID: reatmon@jabber.org
 +
 
 +
'''Peter Saint-Andre'''
 +
 
 +
Email: [mailto:stpeter@jabber.org stpeter@jabber.org]
 +
 
 +
JabberID: stpeter@jabber.org
 +
 
 +
URI: https://stpeter.im/
 +
 
 +
{{Template:XEP附录CDEF}}
 +
 
 +
===附录G:备注===
 +
 
 +
# RFC 3920: 可扩展的消息和出席信息协议 (XMPP): Core <http://tools.ietf.org/html/rfc3920>.
 +
# XEP-0011: Jabber Browsing <http://xmpp.org/extensions/xep-0011.html>.
 +
# XEP-0094: Agent Information <http://xmpp.org/extensions/xep-0094.html>.
 +
# XEP-0134: XMPP Design Guidelines <http://xmpp.org/extensions/xep-0134.html>.
 +
# SOAP <http://www.w3.org/TR/SOAP/>.
 +
# RFC 3921: 可扩展的消息和出席信息 (XMPP): Instant Messaging and Presence <http://tools.ietf.org/html/rfc3921>.
 +
# XEP-0013: Flexible Offline Message Retrieval <http://xmpp.org/extensions/xep-0013.html>.
 +
# XEP-0060: Publish-Subscribe <http://xmpp.org/extensions/xep-0060.html>.
 +
# XEP-0118: User Tune <http://xmpp.org/extensions/xep-0118.html>.
 +
# XEP-0115: Entity Capabilities <http://xmpp.org/extensions/xep-0115.html>.
 +
# XEP-0055: Jabber Search <http://xmpp.org/extensions/xep-0055.html>.
 +
# XEP-0086: Error Condition Mappings <http://xmpp.org/extensions/xep-0086.html>.
 +
# 无论如何, 服务器可以 MAY 返回条目而不是可用的资源(如果有).
 +
# 互联网编号分配机构(IANA) 是用于互联网协议的唯一性参数值分配的核心协调者, 例如号码和URI计划. 更多信息, 见 <http://www.iana.org/>.
 +
# XMPP登记员XMPP Registrar 维护着一个保留的协议名字空间以及用于由XMPP标准基金会批准的XMPP扩展协议的上下文参数的注册项的列表. 更多信息, 见 <http://xmpp.org/registrar/>.
 +
# XEP-0147: XMPP URI Query Components <http://xmpp.org/extensions/xep-0147.html>.
 +
 
 +
===附录H:修订历史===
 +
 
 +
注意: 本协议的旧版本可能在 http://xmpp.org/extensions/attic/ 还可用
 +
 
 +
'''版本 2.4 (2008-06-06)'''
 +
 
 +
会议达成共识, 移除了 disco-publish 特性 (实现应该使用 publish-subscribe 代替).
 +
 
 +
(psa)
 +
 
 +
'''版本 2.3 (2007-02-15)'''
 +
 
 +
增加了关于实体能力的实现备注.
 +
 
 +
(psa)
 +
 
 +
'''版本 2.2 (2006-01-24)'''
 +
 
 +
更多和服务器处理发送给纯JIDs的请求相关的特定的和澄清了安全事项.
 +
 
 +
(psa)
 +
 
 +
'''版本 2.1 (2005-03-03)'''
 +
 
 +
增加了关于服务器处理发送给纯JIDs的请求的实现备注.
 +
 
 +
(psa)
 +
 
 +
'''版本 2.0 (2004-07-20)'''
 +
 
 +
通过Jabber理事会的投票, 状态升级为最终版.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.10 (2004-06-29)'''
 +
 
 +
定义了安全事项; 修改了扩展的出席信息例子来使用一个虚拟的协议; 更多特定的 publish 特性; 定义了注册项提交.
 +
 
 +
(psa/jjh)
 +
 
 +
'''版本 1.9 (2004-05-27)'''
 +
 
 +
澄清了错误条件.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.8 (2004-05-21)'''
 +
 
 +
移除了多余的特性协商文本到 XEP-0020.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.7 (2004-05-13)'''
 +
 
 +
增加了实现备注关于特性和条目结果的可伸缩性; 最后的社论清理.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.6 (2004-05-11)'''
 +
 
 +
纠正了发布可用条目的例子; 更多澄清节点层次结构的性质.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.5 (2004-05-10)'''
 +
 
 +
增加了澄清节点层次结构的备注.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.4 (2004-05-07)'''
 +
 
 +
澄清 "directory"的用法; 增加章节定义一个实体和与它相关的条目之间的关系.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.3 (2004-04-23)'''
 +
 
 +
更多澄清条目发布 item-publication 协议; 移除一些特性协商文本到 XEP-0020; 增加关于知名服务发现节点的注册项的信息; 增加关于遍历树和大结果集的实现备注; 附加了征集经验建议.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.2 (2004-04-20)'''
 +
 
 +
社论清理; 附加了一些经验建议征集.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.1 (2004-03-15)'''
 +
 
 +
以更正式的方式描述了需求, 语法, 和用例; 纠正了一些例子和schemas中的错误; 定义了 XMPP 登记处的程序; 增加了参考的号码; 定义了 XMPP 错误处理.
 +
 
 +
(psa)
 +
 
 +
'''版本 1.0 (2003-04-21)'''
 +
 
 +
通过Jabber理事会的投票, 提升状态为草案; 同时添加 XML schemas.
 +
 
 +
(psa)
 +
 
 +
'''版本 0.13 (2003-02-25)'''
 +
 
 +
增加了关于空节点的备注; 描述了关于多个 identity 元素的语义.
 +
 
 +
(pgm)
 +
 
 +
'''版本 0.12 (2003-02-06)'''
 +
 
 +
增加了对IQ-set的支持; 增加了关于 disco#info 到一个节点的例子.
 +
 
 +
(pgm)
 +
 
 +
'''版本 0.11 (2002-12-17)'''
 +
 
 +
根据标准列表里的讨论增加了对 'node' 属性的支持,以支持不可定址为JID的条目.
 +
 
 +
(psa)
 +
 
 +
'''版本 0.10 (2002-11-21)'''
 +
 
 +
修改了 <feature type='foo'/> 成为 <feature var='foo'/> 以跟踪特性协商的变化 (XEP-0020); 增加了初始的注册项参数.
 +
 
 +
(psa)
 +
 
 +
'''版本 0.9 (2002-11-07)'''
 +
 
 +
增加了 disco#item对空结果集的支持.
 +
 
 +
(psa)
 +
 
 +
'''版本 0.8 (2002-11-01)'''
 +
 
 +
对于item查询,移除了 max, start, 和 total 属性(这将由一个通用的分页协议来处理); 增加了 "http://jabber.org/protocol/feature-neg" 名字空间作为一个特性用于发出关于一个或多个特性的协商信号.
 +
 
 +
(psa)
 +
 
 +
'''版本 0.7 (2002-10-28)'''
 +
 
 +
清理特性文本和例子.
 +
 
 +
(psa)
 +
 
 +
'''版本 0.6 (2002-10-27)'''
 +
 
 +
增加了 'category' 属性到 <feature/> 元素; 增加了安全性, IANA, 和 XMPP 登记处 事项; 增加了例子的编号.
 +
 
 +
(psa)
 +
 
 +
'''版本 0.5 (2002-10-15)'''
 +
 
 +
全部翻修和简化
 +
 
 +
(psa)
 +
 
 +
'''版本 0.4 (2002-07-16)'''
 +
 
 +
重要补充和修正,更多的例子。
 +
 
 +
(psa)
 +
 
 +
'''版本 0.3 (2002-05-30)'''
 +
 
 +
围绕用例重新组织,做了一些小的修补。
 +
 
 +
(psa)
 +
 
 +
'''版本 0.2 (2002-05-05)'''
 +
 
 +
合并合著者的评论并增加备注.
  
+
(psa)
  
'''注释'''
+
'''版本 0.1 (2002-05-03)'''
  
+
初始的草案.
  
'''修订历史'''
+
(psa)
  
+
结束

2011年2月15日 (二) 08:02的最后版本


本文的英文原文来自XEP-0030

XEP-0030:服务发现

摘要: 本文定义了一个XMPP协议扩展用于发现其他XMPP实体的信息.有两种信息可以被发现:(1) 一个实体的身份和能力, 包括它支持的协议和特性; (2) 和一个实体相关的条目, 例如一个多用户聊天服务的房间列表.

作者: Joe Hildebrand, Peter Millard, Ryan Eatmon, Peter Saint-Andre

版权: © 1999 - 2010 XMPP标准化基金会(XSF). 参见法律通告.

状态: 最终

类型: 标准跟踪

版本: 2.4

最后更新日期: 2008-06-06

注意: 这里定义的协议是XMPP标准化基金会的一个最终标准,对于实现和布署来说可以被认为是一个稳定技术.

目录

绪论

在Jabber网络中发现实体相关信息的能力是极有价值的。这些信息包括实体支持的特性或支持的协议、实体的类型或身份、同原实体以某种方式相联系的另外一些实体等(这些实体通常当作“父”实体的“子”实体)。虽然XMPP Core 1并没有定义怎样做的机制,但在Jabber社区内,过去已经有几个协议用在了服务发现上,特别是 Jabber Browsing 2Agent Information 3上。然而,这些协议总使人感觉不那么合适,其原因如下:

  1. Jabber Browsing 和 Agent Information 都不容易扩展。例如,在XEP-0011中列出JID类型的种类及子类都明确地定义为唯一的正式种类,向列表加入新的JID类型都要修改XEP-0011。而Jabber Browsing规范允许用非正式种类和以‘x-’打头的类型,这会产生移植问题。这种适应性的缺乏违反了Jabber社区的核心XMPP协议设计原则 4之一 。
  2. 在 Agent Information 协议中,没有声明所支持的特性的方法。虽然Jabber Browsing包含了这样的机制,但表达一个特性的有效性的唯一方法是声明一个所支持的名字空间。然而,有些特性也许并非唯一地对应一个协议名字空间,它只是特性的一个实现,但并是唯一的一个。
  3. 一个Jabber Browsing 结果返回一个组合,由(1)Jabber实体支持的名字空间,(2)与Jabber实体相关联的条目,(3)相关条目支持的名字空间组成。这种方法混淆了信息级别,要求父节点知晓子节点的一切,也就引入了极大的混乱。
  4. 在Jabber Browsing 和 Agent Information中,要求条目们(items)必须可寻址为JIDs;然而,这在有些应用中是做不到的。

本文档旨在克服Jabber Browsing和Agent Information这两个协议的弱点。其结果就是一个用于服务发现的标准追踪协议(通常缩写为“disco”,就和一些熟悉的协议,如 SOAP 5一样)。

需求

在作者的头脑中构思的服务发现协议要满足下面的需求:

  • 协议 必须 支持它所取代的协议(Jabber Browsing 和 Agent Information)之全部功能
  • 有三种关于一个实体的信息需要发现:
  1. 它的基本身份(类型和/或目录)
  2. 它提供的特性和支持的协议
  3. 与实体相关联的任何附加条目,无论它们是否能定址为JID

三种信息都 必须 支持,但前两种信息都与实体本身有关,而第三种信息与实体关联的条目有关;因此只需要两种不同的查询类型。

  • 子条目信息的发现 必须 通过向它自己,而不是向父实体,发送单独的发现请求实现。(其后果之一是,要发现整个三种信息,需要多个请求/响应对,以“遍历整个信息树”)。
  • 身份和特性列表 必须 是柔性的。
  • 协议本身 必须 是可扩展的。

发现Jabber实体的信息

基本协议

一个发出请求的实体会想发现网络中另一个实体的信息。想得到的信息一般分为两种:

  1. 目标实体的身份(identity)。在disco中,一个实体的身份细分成种类(category)(服务器、客户端、网关、目录等等)及其种类中的特殊类型(IM服务器、电话对处理的客户端、MSN网关对AIM网关、用户目录对聊天室目录等等)。这个信息帮助请求实体测定服务组或服务“桶”,以使实体最恰当地放置其中(例如,或许用个合适的图标把实体显示成GUI)。一个实体 可以 有多个身份。当提供多个identity元素的时候,每个identity元素的 name 属性 应该 有相同的值。
  2. 目标实体提供的特性和支持的协议。这个信息帮助请求实体测定对目标实体可以做什么样的动作(注册、搜索、联合等等),实体支持什么样的协议,以及是否有感兴趣的特性类型(例如,为了特性协商的目的)。

为了发现这样的信息,请求实体 必须 向目标实体的JID发送类型为“get”的IQ节,包含一个用命名空间 'http://jabber.org/protocol/disco#info' 标识的空的 <query/> 元素('to'的地址是 必需的必须 包含有效的JID;<query>元素的'node'属性是 可选的 ,本文中 信息节点条目节点 一节对此有说明)。

例1. 查询信息

<iq type='get'
    from='romeo@montague.net/orchard'
    to='plays.shakespeare.lit'
    id='info1'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

然后目标实体 必须 返回一个IQ结果,或者返回一个错误(见本文错误条件)。结果 必须 包含用命名空间'http://jabber.org/propocol/disco#info'标识的<query/>元素,元素中依次包含一个或多个<identity/>元素及一个或多个<feature/>元素。(注意:每个实体 必须 至少有一个identity,每个实体 必须 至少支持 'http://jabber.org/protocol/disco#info' 特性;然而,并不要求一个实体一定返回一个结果,它也 可以 返回一个错误,最可能的是 <feature-not-implemented/> 或 <service-unavilable/>,虽然其他出错条件也是可以的)。

每个<identity/>元素 必须 拥有'category'和'type'属性,用来说明实体的种类, 而且可以 MAY 拥有一个 'name' 属性为这个实体指定一个自然语言的名字; 这个 <identity/> 元素也可以 MAY 拥有一个标准的 'xml:lang' 属性, 它使实体能返回本地化的结果,如果必要的话(即, <query/> 元素可以 MAY 包含多个 <identity/> 元素,使用相同的 category+type 但是不同的 'xml:lang' 值;无论如何 <query/> 元素不能 MUST NOT 以相同的 category+type+xml:lang 和不同的 'name' 值包含多个 <identity/> 元素,).

每个<feature/>元素 必须 拥有一个'var'属性,它的值是协议的命名空间或是实体提供的其他特性。

如果象本文中XMPP登记事项一节说明的那样,种类/类型的值和特性值都在公共登记处注册了的话就更好了。

例2. 信息请求的结果集

<iq type='result'
    from='plays.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='info1'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        type='text'
        name='Play-Specific Chatrooms'/>
    <identity
        category='directory'
        type='chatroom'
        name='Play-Specific Chatrooms'/>
    <feature var='http://jabber.org/protocol/disco#info'/>
    <feature var='http://jabber.org/protocol/disco#items'/>
    <feature var='http://jabber.org/protocol/muc'/>
    <feature var='jabber:iq:register'/>
    <feature var='jabber:iq:search'/>
    <feature var='jabber:iq:time'/>
    <feature var='jabber:iq:version'/>
  </query>
</iq>

如果指定目标实体的JID不存在,服务器或其他认证实体 应该 返回一个<item-not-found/>错误,除非如果这么做会破坏在XMPP CoreXMPP IM 6中说明的隐私和安全事项,或是破坏本地隐私和安全策略(见本文安全事项):

例3. 目标实体不存在

<iq type='error'
    from='plays.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='info1'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
  <error code='404' type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

如果隐私和安全事项或策略阻止服务器或其他授权实体返回<item-not-found/>错误,取而代之它 应该 返回一个<service-unavailable/>错误:

例4. 服务不可用

<iq type='error'
    from='plays.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='info1'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
  <error code='503' type='cancel'>
    <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

当一个实体向一个由服务器做宿主的纯JID(<account@domain.tld>)发送disco#info请求的时候,这个服务器本身 必须 代表寄宿的帐号回应一个IQ错误或IQ结果。有关访问这些功能的重要规则,见本文的安全事项一节。特别地,为响应向一个没有节点的纯JID发出的disco#info请求,如果访问没被拒绝,服务器 应该 为这个纯JID返回一个IQ结果,里面的主 identity 应该 有具有合适类型的“account”种类,类型在 Service Discovery Identities 注册中说明(最可能的是类型"registered")。注意:这使得那些已授权或被信任的实体能发现帐号帐号是否存在及帐号的类型(例如,在IM系统中,在把帐号加入联系人列表之前检测它是否存在)。

例5. 从纯JID那里请求信息

<iq type='get'
    from='shakespeare.lit'
    to='juliet@capulet.com'
    id='info2'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

这里我们假定shakespeare.lit被capulet.com信任,而帐号<juliet@capulet.com>是个注册帐号:

例 6. 服务器替纯JID应答

<iq type='result'
    from='juliet@capulet.com'
    to='shakespeare.lit'
    id='info2'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity category='account' type='registered'/>
  </query>
</iq>

向关联实体发出的查询结果会不同,或能得到更详细的信息。一个例子是向一个特别的会议室而不是父实体的会议服务发出查询:

例7. 查询指定的会议室

<iq type='get'
    from='juliet@capulet.com/balcony'
    to='balconyscene@plays.shakespeare.lit'
    id='info3'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
 
<iq type='result'
    from='balconyscene@plays.shakespeare.lit'
    to='juliet@capulet.com/balcony'
    id='info3'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        type='text'
        name='Romeo and Juliet, Act II, Scene II'/>
    <feature var='http://jabber.org/protocol/disco#info'/>
    <feature var='http://jabber.org/protocol/muc'/>
    <feature var='http://jabber.org/protocol/feature-neg'/>
    <feature var='muc-password'/>
    <feature var='muc-hidden'/>
    <feature var='muc-temporary'/>
    <feature var='muc-open'/>
    <feature var='muc-unmoderated'/>
    <feature var='muc-nonanonymous'/>
  </query>
</iq>

另一个例子是向一个带明确资源连接的IM用户发出查询:

例 8. 查询连接资源的更详细的信息

<iq type='get'
    from='juliet@capulet.com/balcony'
    to='romeo@montague.net/orchard'
    id='info4'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
 
<iq type='result'
    from='romeo@montague.net/orchard'
    to='juliet@capulet.com/balcony'
    id='info4'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='client'
        type='pc'
        name='Gabber'/>
    <feature var='jabber:iq:time'/>
    <feature var='jabber:iq:version'/>
  </query>
</iq>

信息节点

一个 disco#info 也查询可以 MAY 被定向到特定的关联到一个JID的节点标识符, 尽管节点的主要用途是成为条目节点 Items Nodes 而不是信息节点 info nodes:

例子 9. 查询一个特定的JID和node的组合

<iq type='get'
    from='romeo@montague.net/orchard'
    to='mim.shakespeare.lit'
    id='info3'>
  <query xmlns='http://jabber.org/protocol/disco#info' 
         node='http://jabber.org/protocol/commands'/>
</iq>

如果请求包含 'node' 属性, 应答必须 MUST 镜像这个指定的 'node' 属性以确保请求和应答之间的相关性.

例子 10. JID+node结果

<iq type='result'
    from='mim.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='info3'>
  <query xmlns='http://jabber.org/protocol/disco#info' 
         node='http://jabber.org/protocol/commands'>
    <identity
        category='automation'
        type='command-list'/>
  </query>
</iq>


发现与Jabber实体相关的条目

基本协议

请求实体为了发现一个Jabber实体相关联的条目,它 必须 向目标实体发送类型为"get"的IQ节,其中包含一个空的<query/>元素,受限命名空间为 'http://jabber.org/protocol/disco#items':

例11. 请求全部条目

<iq type='get'
    from='romeo@montague.net/orchard'
    to='shakespeare.lit'
    id='items1'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

目标实体 必须 返回它的公开可用的条目列表,或者返回一个错误。条目列表 必须 是类型为"result"的IQ段,每个条目用<query/>的子元素<item/>来说明,受限命名空间是 'http://jabber.org/protocol/disco#items' (子元素 <item/> 必须 用'jid'属性指定条目的JID, 可以 用'name'属性说明条目的自然语言名):

例12. 所有条目的结果集

<iq type='result'
    from='shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='items1'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='people.shakespeare.lit'
          name='Directory of Characters'/>
    <item jid='plays.shakespeare.lit'
          name='Play-Specific Chatrooms'/>
    <item jid='mim.shakespeare.lit'
          name='Gateway to Marlowe IM'/>
    <item jid='words.shakespeare.lit'
          name='Shakespearean Lexicon'/>
    <item jid='globe.shakespeare.lit'
          name='Calendar of Performances'/>
    <item jid='headines.shakespeare.lit'
          name='Latest Shakespearean News'/>
    <item jid='catalog.shakespeare.lit'
          name='Buy Shakespeare Stuff!'/>
    <item jid='en2fr.shakespeare.lit'
          name='French Translation Service'/>
  </query>
</iq>

<item/>元素 必须不可 包含XML字符数据,并 应该 是空元素;当然它 可以 在其他命名空间中包含XML数据,如果一个Jabber实现不理解这些数据,则 必须 忽略它。

如果没有条目与实体相关联(或者这些条目并非公开可用的),目标实体必须向请求实体返回一个空的query元素:

例13. 空的结果集

<iq type='result'
    from='shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='items1'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

就请求disco#info来说,当实体向寄生在一个服务器的纯JID(<account@domain.tld>)发送disco#items请求时,宿主服务器自身 必须 代表寄生帐号回应。有关访问这个功能的重要准则,见本文的安全事项一节。特别地,为响应发到一个不带节点的纯JID的disco#info请求,如果访问没被拒决,服务器 应该 返回相关的条目,包括适当的已连接或可用的资源:

例14. 从一个纯JID请求条目

<iq type='get'
    from='shakespeare.lit'
    to='juliet@capulet.com'
    id='items2'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

在这儿我们假设shakespeare.lit被capulet.com信任,帐号<juliet@capulet.com>有两个可用的资源:

例15. 服务器代表纯JID响应

<iq type='result'
    from='juliet@capulet.com'
    to='shakespeare.lit'
    id='items2'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='juliet@capulet.com/balcony'/>
    <item jid='juliet@capulet.com/chamber'/>
  </query>
</iq>

条目节点

与实体相关联的条目有可能不能写成JID地址的形式;这样的例子包括,储存在收件箱的离线消息(见柔性离线消息获取 7)、有Jabber能力的博客中的条目、与一个客户或组件关联的XML-RPC服务、在一个在线交易系统中的可用条目 (例如, 一个目录或拍卖)、位于一个NNTP网关的新闻贴、及由发布-订阅 8组件 主办的主题等等。为处理这些条目,<item/>元素 可以 有个 可选的 'node'属性来补充这个 必须的 'jid'属性。

节点的属性值可以有或没有语义上的含义;从服务发现的观点来看,一个节点只不过是个与实体相联系的某种东西。为了发现节点更多的东西,请求实体 必须 在查询实体的JID的时候指定节点。如果'node'属性的值有语义上的含义,意味着这个含义是由"使用的协议"或应用提供的,而不是由服务发现协议决定的。不应该 包含节点属性,除非需要提供,或者要发现信息的实体不能直接写成JID地址的形式(就是说,如果相关的条目能写成一个JID就不要包含一个节点)。'node'属性的值 必须不能 为空。

在下面的例子中,用户从一个在线目录服务中请求所有可用的条目:

例16. 请求节点

<iq type='get'
    from='romeo@montague.net/orchard'
    to='catalog.shakespeare.lit'
    id='items2'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

如果有与目标实体相关的条目但它们不能写成JID地址,那么服务 应该 返回一个节点列表(每个<item/>元素 必须 有一个'jid'属性, 应该 有个'node'属性, 可以 有个'name'属性):

例17. 服务返回节点

<iq type='result'
    from='catalog.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='items2'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='catalog.shakespeare.lit'
          node='books'
          name='Books by and about Shakespeare'/>
    <item jid='catalog.shakespeare.lit'
          node='clothing'
          name='Wear your literary taste with pride'/>
    <item jid='catalog.shakespeare.lit'
          node='music'
          name='Music from the time of Shakespeare'/>
  </query>
</iq>

在返回上面的查询时,也许有更多的节点与"第一级"节点相关联(比如,节点可能是一个类别,有下级条目)。请求实体可以通过向这个JID发送请求,并在请求中说明感兴趣的节点,来进一步查询节点。

例18. 请求更多的节点

<iq type='get'
    from='romeo@montague.net/orchard'
    to='catalog.shakespeare.lit'
    id='items3'>
  <query xmlns='http://jabber.org/protocol/disco#items' 
         node='music'/>
</iq>

然后服务返回与“父”节点相关的更深层的节点。在下面的例子中,服务本身将返回的节点按字母顺序排序,不过这种结构是实现的问题而不是协议的要求。

例19. 服务返回更深层的节点

<iq type='result'
    from='catalog.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='items3'>
  <query xmlns='http://jabber.org/protocol/disco#items' 
         node='music'>
    <item jid='catalog.shakespeare.lit'
          node='music/A'/>
    <item jid='catalog.shakespeare.lit'
          node='music/B'/>
    <item jid='catalog.shakespeare.lit'
          node='music/C'/>
    <item jid='catalog.shakespeare.lit'
          node='music/D'/>
    .
    .
    .
  </query>
</iq>

如果想要,请求实体可以继续查询更深层的节点:

例20. 请求更深层节点

<iq type='get'
    from='romeo@montague.net/orchard'
    to='catalog.shakespeare.lit'
    id='items4'>
  <query xmlns='http://jabber.org/protocol/disco#items' 
         node='music/D'/>
</iq>

例21. 服务返回更多的节点

<iq type='result'
    from='catalog.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='items4'>
  <query xmlns='http://jabber.org/protocol/disco#items' 
         node='music/D'>
    <item jid='catalog.shakespeare.lit'
          node='music/D/dowland-firstbooke'
          name='John Dowland - First Booke of Songes or Ayres'/>
    <item jid='catalog.shakespeare.lit'
          node='music/D/dowland-solace'
          name='John Dowland - A Pilgrimes Solace'/>
  </query>
</iq>

节点层次结构

前面的例子显示了节点的层次结构,里面的有些节点是分支(也即包含更深层的节点),有些节点是叶子(即不包含更深层的节点)。 应该 用"hierarchy"这个category来区分这些节点,“分支”和“叶子”表示这个种类category的具体类型type。

如果使用了分层种类,层次结构中的每个节点 必须 标识为要么是分支要么是叶子;然而,因为一个节点 可以 有多个身份,所以任一节点也 可以 有一个除了“层次/分支”或“层次/叶子”结构外的身份。

因此,上面显示的例子中,一个向"music/D"的disco#info请求会产生<identity category='hierarchy' type='branch'/>,而向"<music/D/dowland-firstbooke>"节点发出的请求会产生<identity category='hierarchy' type='leaf'/>(每个节点会产生恰当的附加身份)。

实体和其条目的关系

本节要说明的是一个实体和它的相关条目之间更详细的关系。

一般情况下,由一个实体在disco#items结果中返回的条目 必须 是与实体有隶属关系的条目 --或者是实体直接控制条目本身(比如,实体拥有的Publish-Subscribe节点),或者实体至少能以Jabber网络中规范的方式提供或确保这些条目(例如,群聊房间直接寄宿于一个多用户聊天服务或一个通过网关提供访问的IRC频道)。

这样的关系并不限制所属实体的地址与相关实体地址间的关系。特别地,下面任何一种情况都是非常合适的:

  1. 查询一个实体(JID1)的条目时,接收到可定址为JID的条目列表;每个相关条目都有自己的JID,但这些JID都与JID1不相同。
  2. 查询一个实体(JID1)的条目时,接收到不可定址为JID的条目列表;每个相关条目有各自的JID+Node,其中JID与JID1相同但每个NodeId都是唯一的。
  3. 查询一个实体(JID1+NodeID1)的条目时,接收到可定址为JID的条目列表;每个相关条目有自己的JID,但没有JID与JID1相同。
  4. 查询一个实体(JID1+NodeId1)的条目时,接收到不能定址为JID的细节列表;每个相关条目有自己的JID+node,但是没有JID+node与JID1+NodeID1相同,并且每个NodeID都在相关JID的上下文中都是唯一的。

另外,返回的结果也 可以 是混合型的,这样查询一个JID或JID+node会产生(1)定址为JID的项和(2)定址为JID+node这两种的组合。

考虑一下实体的这种情况,它拥有多个 发布-订阅 节点 --例如,一个人拥有多个音乐演奏家节点。下面的例子演示了disco#items查询及其结果会是什么样子(使用了在User Tune 9中定义的协议):

例22. 用户请求有关实体的音乐

<iq from='juliet@capulet.com/chamber'
    id='items4'
    to='romeo@montague.net'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items' 
         node='http://jabber.org/protocol/tune'/>
</iq>

被查询的实体现在返回一个它控制的 发布-订阅publish-subscribe 节点的列表,每个节点寄宿于不同的发布订阅 pubsub 服务:

例23. 实体返回多项条目

<iq from='romeo@montague.net'
    id='items4'
    to='juliet@capulet.com/chamber'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items' 
         node='http://jabber.org/protocol/tune'>
    <item jid='pubsub.shakespeare.lit'
          name='Romeo&apos;s CD player'
          node='s623nms9s3bfh8js'/>
    <item jid='pubsub.montague.net'
          node='music/R/Romeo/iPod'/>
    <item jid='tunes.characters.lit'
          node='g8k4kds9sd89djf3'/>
  </query>
</iq>

发布可用的条目

这个特性已经被移到定义 XMPP 发行-订阅 技术的 XEP-0060 中去了.

实现注意事项

信息请求数

当发出请求的应用是一个客户端的时候,在用户收到好友名册并收到名册中所有联系人的出席信息(例如, 展示可用)后,它也许想得到所有联系人的服务发现信息。不幸的是,用户的花名册可能很长,结果登录后会向外发出大量的disco#info查询和接收进来大量的disco#info响应。基于可扩展性和带宽利用的原因,并不希望有这种“发现洪流”,因此,客户端应用 应该实体能力 10来确定它们接收到了出席信息的那些实体的能力,而 不应该 向这些实体发送disco#info请求。

请求的条目数

为了获取实体及相关条目的完整信息,发出请求的应用程序需要“遍历”细节树。很自然,这会产生大量的请求和响应。如果条目列表很长的话(比如,超过20条),发出请求的应用程序接下来 不应该 对所有的条目发送请求。日常需要维护大量条目的那些实体(如IRC网关或NNTP服务) 应该 将节点组织成层次结构,并且/或者通过像 Jabber Search 11之类的协议,提供更健壮的搜索能力; 不应该 通过服务发现返回极其巨大的结果集。

响应一致性

本文档推荐但并不要求响应实体对来自不同的请求实体的相同的请求返回一样的结果(比如,一个实体基于对请求实体的信任度或是已知能力的不同,可能返回不同的细节或特性列表)。然而,响应实体 应该 对发送到相同的 JID+node 组合的所有disco#info请求返回相同的<identity/>元素(category+type) 。

错误条件

如果特定的实体(JID或JID+node)不支持disco命名空间,拒绝对特定的请求实体或任何请求实体返回disco结果,它 应该 分别返回适当的错误信息(象<service-unavailable/>,<forbidden/>,或<not-allowed/>等等)。示例如下:

例24. JID+node错误

<iq type='error'
    from='mim.shakespeare.lit'
    to='romeo@montague.net/orchard'
    id='info3'>
  <query xmlns='http://jabber.org/protocol/disco#info' 
         node='http://jabber.org/protocol/commands'/>
  <error code='405' type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

根据应用的不同,也可以有其他的错误条件。

下表总结了常见的错误条件,它们在服务发现Service Discovery的上下文中可能有特殊的含义(关于错误条件的语法和语义的信息,见错误条件映射 12)。

表1: 错误条件

条件 原因
<item-not-found/> 指定目标实体的JID或JID+NodeID并不存在,并且依据隐私及安全事项和策略,这一事实可以暴露。
<service-unavailable/> 目标实体不支持这一协议,或者指定的目标实体并不存在,但这一事实因为隐私及安全事项不能暴露。

其他在XMPP Core中说明的错误条件也 可以 返回(<forbidden/>,<not-allowed/>,<not-authorized/>等等),包括应用专有的错误条件。

正象上面说明的那样,如果一个实体没有相关的子条目,它 必须 返回一个空的<query/>元素(而不是一个错误)来响应disco#items请求。

安全事项

当实体暴露(通过disco#info响应)它支持的特定的协议或特性的时候,某些攻击会更容易发生;然而,一般来说,服务发现不会引入新的漏洞,因为恶意实体会通过发送对这些协议的特定的请求而不是服务发现请求,来发现响应实体支持哪些协议和特性。

当响应实体应答从不同的请求实体接收到的服务发现请求的时候,它没有义务返回相同的服务发现响应。 它 可以 在响应前执行授权检测,以决定怎样(或是否)响应。

服务器 必须 小心地控制对任何可能导致目录获取攻击或泻露已连接或可用资源的功能的访问,这些功能由服务器对发送到寄宿其中的纯JID(地址型如account@domain.tld)的disco#info和disco#items请求的响应组成,因为服务器要代表这个帐户响应这样的请求。处理发送到纯JID的服务发现请求时应用如下规则:

1. 为了响应disco#info请求,如果下列条件之一为真,服务器 必须 返回<service-unavailable/>错误:

  1. 目标实体不存在(无论请求指定的是否是一个节点)
  2. 请求实体未经授权从目标实体接收出席信息(也即,出席信息订阅的类型是"both"或"from"),或者请求实体不被信任(例如,在一个信任网络中的另一个服务器)。

2. 为了响应disco#items请求,服务器 必须 返回一个空结果集,如果:

  1. 目标实体不存在(无论请求指定的是否是一个节点)
  2. 请求没有指定节点,唯一的条目是可用的资源(象在RFC3921中定义的那样),并且请求实体未经授权从目标实体接收出席信息(也即,出席信息订阅的类型是"both"或"from"),或者请求实体不被信任(例如,在一个信任网络中的另一个服务器)13

IANA事项

本文档与互联网编号分配授权机构 14无关。

XMPP登记事项

协议名字空间

XMPP Registrar 15在它的协议名字空间注册项中包含了 'http://jabber.org/protocol/disco#info' 和 'http://jabber.org/protocol/disco#items' 名字空间

登记处

身份种类及类型登记

XMPP登记处 XMPP Registrar 维护着命名空间'http://jabber.org/protocol/disco#info'里<identity/>元素的属性的'category'和'type'的注册值;见<http://www.xmpp.org/registrar/disco-categories.html>

过程

为了向注册项提交新值,注册人将按如下的形式定义XML段,然后将其包含在相关的XMPP扩展协议中或是发送邮件到<registrar@xmpp.org>:

<category>
  <name>the name of the category (all lower-case)</name>
  <desc>a natural-language description of the category</desc>
  <type>
    <name>the name of the specific type (all lower-case)</name>
    <desc>a natural-language description of the type</desc>
    <doc>the document (e.g., XEP) in which this type is specified</doc>
  </type>
</category>

注册人每次可以注册一个以上的种类,每个种类包含在独立的<category/>元素中。每个注册人也可以每次注册一个以上的类型,每个类型包含在独立的<type/>子元素中。已有种类中的新类型的注册必须包含完整的XML片段,但不应包含种类的描述(仅有种类的名称)。

初始提交

本文档定义了一个种类的“层次结构”,它仅包含两个类型:“branch”和“leaf”;相关的注册提交项如下:

<category>
  <name>hierarchy</name>
  <desc>
    An entity that exists in the context of a 
    service discovery node hierarchy.
  </desc>
  <type>
    <name>branch</name>
    <desc>
      A "container node" for other entities in a 
      service discovery node hierarchy.
    </desc>
    <doc>XEP-0030</doc>
  </type>
  <type>
    <name>leaf</name>
    <desc>
      A "terminal node" in a service discovery 
      node hierarchy.
    </desc>
    <doc>XEP-0030</doc>
  </type>
</category>

特性注册

XMPP登记处维护着一个特性注册项,用于遵循 'http://jabber.org/protocol/disco#info' 名字空间的 <feature/> 元素的 'var' 属性的值;见<http://xmpp.org/registrar/disco-features.html>>。

过程

为了向注册表提交新值,注册人必须按如下格式定义一个XML片段,将它包含在相关的XMPP扩展协议中,或者发到<registrar@xmpp.org>:

<feature var='name of feature or namespace'>
  <desc>a natural-language description of the feature</desc>
  <doc>the document (e.g., XEP) in which this feature is specified</doc>
</feature>

注册人可一次注册一个以上的特性,每个特性包含在独立的<feature>元素中。

知名节点

一个正在使用的协议可以指定一个或以上的服务发现节点,这些节点在协议上下文中有特殊的、恰当定义的含义。为了全局性地跨所有Jabber协议保留这些节点名字,XMPP登记处在<http://www.xmpp.org/registrar/nodes.html>维护着一个知名服务发现节点的注册。

过程

为了向登记处提交新值,注册人必须按如下格式定义一个XML片段,然后将它包含在相关的XMPP扩展协议中,或者发邮件到<registrar@xmpp.org>:

<node>
  <name>the name of the node</name>
  <desc>a natural-language description of the node</desc>
  <doc>the document (e.g., XEP) in which this node is specified</doc>
</node>

注册人可以一次注册一个以上的节点,每个节点包含在单独的<node/>元素中。

URI查询类型

作为由XMPP URI Query Components 16授权的机构,XMPP登记处维护着一个用于 XMPP URIs 的查询和键-值对的注册项(见<http://www.xmpp.org/registrar/querytypes.html>)。

在这里定义了用于服务发现交互的查询类型“disco”,它有三个键:(1)"node"(查询的可选节点),(2)"request"(带“info”值来取回服务发现信息,带“items”值取回服务发现条目),(3)“type”(带值“get”用于IQ取值,“set”用于IQ设置)。

例25. 服务发现信息请求:IRI/URI

xmpp:romeo@montague.net?disco;type=get;request=info

例26. 服务发现信息请求:结果节

<iq to='romeo@montague.net' type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

例27. 服务发现条目请求: IRI/URI

xmpp:romeo@montague.net?disco;type=get;request=items

例28. 服务发现条目请求:结果节

<iq to='romeo@montague.net' type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

下列提交注册"disco"查询类型。

<querytype>
  <name>disco</name>
  <proto>http://jabber.org/protocol/disco</proto>
  <desc>enables interaction for the purpose of service discovery</desc>
  <doc>XEP-0030</doc>
  <keys>
    <key>
      <name>node</name>
      <desc>the (optional) service discovery node</desc>
    </key>
    <key>
      <name>request</name>
      <desc>the service discovery request type</desc>
      <values>
        <value>
	  <name>info</name>
          <desc>a service discovery information (disco#info) request</desc>
        </value>
        <value>
	  <name>items</name>
          <desc>a service discovery items (disco#items) request</desc>
        </value>
      </values>
    </key>
    <key>
      <name>type</name>
      <desc>the IQ type</desc>
      <values>
        <value>
	  <name>get</name>
          <desc>an IQ get</desc>
        </value>
        <value>
	  <name>set</name>
          <desc>an IQ set (disco publish)</desc>
        </value>
      </values>
    </key>
  </keys>
</querytype>

XML架构

disco#info

<?xml version='1.0' encoding='UTF-8' ?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/disco#info'
    xmlns='http://jabber.org/protocol/disco#info'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0030: http://www.xmpp.org/extensions/xep-0030.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:element name='query'>
    <xs:complexType>
      <xs:sequence minOccurs='0'>
        <xs:element ref='identity' maxOccurs='unbounded'/>
        <xs:element ref='feature' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='node' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='identity'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='category' type='xs:string' use='required'/>
          <xs:attribute name='name' type='xs:string' use='optional'/>
          <xs:attribute name='type' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='feature'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='var' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
 
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
 
</xs:schema>

disco#items

<?xml version='1.0' encoding='UTF-8' ?>
 
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/disco#items'
    xmlns='http://jabber.org/protocol/disco#items'
    elementFormDefault='qualified'>
 
  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-0030: http://www.xmpp.org/extensions/xep-0030.html
    </xs:documentation>
  </xs:annotation>
 
  <xs:element name='query'>
    <xs:complexType>
      <xs:sequence minOccurs='0'>
        <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='node' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>
 
  <xs:element name='item'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='action' use='optional'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='remove'/>
                <xs:enumeration value='update'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
          <xs:attribute name='jid' type='xs:string' use='required'/>
          <xs:attribute name='name' type='xs:string' use='optional'/>
          <xs:attribute name='node' type='xs:string' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
 
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
 
</xs:schema>

作者备注

Peter Millard, 本文的一个合著者,从版本0.1到版本2.2, 死于2006年4月26日.

附录

附录A:文档信息

系列:XEP

序号:0030

发布者:XMPP标准基金会

状态:终结版

类型:标准跟踪

版本:2.4

最后更新:2008-06-06

批准机构:XMPP理事会

依赖标准:XMPP Core

替代标准:XEP-0011, XEP-0094

被替代标准:无

缩略名:disco

disco#info名字空间的XML架构(Schema)[1]

disco#items名字空间的XML方案(Schema)[2]

注册项: <http://xmpp.org/registrar/disco.html>

原文控制: HTML RSS

本文的其它格式: XML PDF

附录B:作者信息

Joe Hildebrand

Email: jhildebr@cisco.com

JabberID: hildjj@jabber.org

Peter Millard

作者备注

Ryan Eatmon

Email: reatmon@jabber.org

JabberID: reatmon@jabber.org

Peter Saint-Andre

Email: stpeter@jabber.org

JabberID: stpeter@jabber.org

URI: https://stpeter.im/

附录C:法律通告

版权

XMPP扩展协议的版权(1999-2008)归XMPP标准化基金会(XSF)所有.

权限

特此授权,费用全免,对任何获得本协议副本的人,对使用本协议没有限制,包括不限制在软件程序中实现本协议,不限制在网络服务中布署本协议,不限制拷贝,修改,合并,发行,翻译,分发,转授,或销售本协议的副本,被允许使用本协议做了以上工作的人士,应接受前述的版权声明和本许可通知并且必须包含在所有的副本或实质性部分的规格中.除非单独的许可,被重新分发的修改工作,不得含有关于作者,标题,编号,或出版者的规格的误导性资料,并不得宣称修改工作是由本文的作者,作者所属的任何组织或项目,或XMPP标准基金会签注。

免责声明'

## 特别注意:本协议是提供的“原样”的基础,没有担保或任何形式的条件,明示或暗示,包括,但不限于任何担保或关于名称,非侵权性,适销性或适合作某一特定目的的条件. ##

责任限制

在任何情况下以及没有任何法律规定时,不论是侵权行为(包括疏忽),合同或其它方面,除非根据适用法律的要求(如蓄意和有严重疏忽行为)或以书面形式同意,XMPP标准基金会或任何作者不对本协议所造成的损失承担责任,包括任何直接,间接,特殊,偶发,或任何从本协议出,入,连接的字符产生的或实现,布署或其他对本协议的使用导致的相应的损害赔偿(包括但不限于善意的损失,停止作业,电脑失灵或故障,或任何和所有其他商业损害或损失) ,即使XMPP标准基金会或作者已被告知此类损害的可能性。

知识产权的一致性

XMPP扩展协议完全遵守XSF的知识产权策略(可在<http://www.xmpp.org/extensions/ipr-policy.shtml>找到副本或写信给XMPP标准基金会, 1899 Wynkoop Street, Suite 600, Denver, CO 80202 USA).

附录D:和XMPP的关系

可扩展的消息和出席信息协议 (XMPP) 定义于 XMPP Core (RFC 3920) 和 XMPP IM (RFC 3921) 规范里,由 XMPP标准基金会贡献到由依据RFC 2026成立的互联网工程人物组管理的互联网标准流程 Internet Standards Process. 本文定义的任何协议已在互联网标准流程之外开发,并且被理解为 XMPP 的扩展而不是一个XMPP本身的演化, 开发, 或修改.

附录E:讨论地点

主要的XMPP扩展协议讨论地点是 <standards@xmpp.org> 讨论列表.

在 xmpp.org 的其它讨论列表中的讨论可能也有合适的; 所有的列表见 <http://xmpp.org/about/discuss.shtml> .

勘误表可以发送邮件到 <editor@xmpp.org>.

附录F:需求一致性

以下用于本文的需求关键字的解释见于 RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".


附录G:备注

  1. RFC 3920: 可扩展的消息和出席信息协议 (XMPP): Core <http://tools.ietf.org/html/rfc3920>.
  2. XEP-0011: Jabber Browsing <http://xmpp.org/extensions/xep-0011.html>.
  3. XEP-0094: Agent Information <http://xmpp.org/extensions/xep-0094.html>.
  4. XEP-0134: XMPP Design Guidelines <http://xmpp.org/extensions/xep-0134.html>.
  5. SOAP <http://www.w3.org/TR/SOAP/>.
  6. RFC 3921: 可扩展的消息和出席信息 (XMPP): Instant Messaging and Presence <http://tools.ietf.org/html/rfc3921>.
  7. XEP-0013: Flexible Offline Message Retrieval <http://xmpp.org/extensions/xep-0013.html>.
  8. XEP-0060: Publish-Subscribe <http://xmpp.org/extensions/xep-0060.html>.
  9. XEP-0118: User Tune <http://xmpp.org/extensions/xep-0118.html>.
  10. XEP-0115: Entity Capabilities <http://xmpp.org/extensions/xep-0115.html>.
  11. XEP-0055: Jabber Search <http://xmpp.org/extensions/xep-0055.html>.
  12. XEP-0086: Error Condition Mappings <http://xmpp.org/extensions/xep-0086.html>.
  13. 无论如何, 服务器可以 MAY 返回条目而不是可用的资源(如果有).
  14. 互联网编号分配机构(IANA) 是用于互联网协议的唯一性参数值分配的核心协调者, 例如号码和URI计划. 更多信息, 见 <http://www.iana.org/>.
  15. XMPP登记员XMPP Registrar 维护着一个保留的协议名字空间以及用于由XMPP标准基金会批准的XMPP扩展协议的上下文参数的注册项的列表. 更多信息, 见 <http://xmpp.org/registrar/>.
  16. XEP-0147: XMPP URI Query Components <http://xmpp.org/extensions/xep-0147.html>.

附录H:修订历史

注意: 本协议的旧版本可能在 http://xmpp.org/extensions/attic/ 还可用

版本 2.4 (2008-06-06)

会议达成共识, 移除了 disco-publish 特性 (实现应该使用 publish-subscribe 代替).

(psa)

版本 2.3 (2007-02-15)

增加了关于实体能力的实现备注.

(psa)

版本 2.2 (2006-01-24)

更多和服务器处理发送给纯JIDs的请求相关的特定的和澄清了安全事项.

(psa)

版本 2.1 (2005-03-03)

增加了关于服务器处理发送给纯JIDs的请求的实现备注.

(psa)

版本 2.0 (2004-07-20)

通过Jabber理事会的投票, 状态升级为最终版.

(psa)

版本 1.10 (2004-06-29)

定义了安全事项; 修改了扩展的出席信息例子来使用一个虚拟的协议; 更多特定的 publish 特性; 定义了注册项提交.

(psa/jjh)

版本 1.9 (2004-05-27)

澄清了错误条件.

(psa)

版本 1.8 (2004-05-21)

移除了多余的特性协商文本到 XEP-0020.

(psa)

版本 1.7 (2004-05-13)

增加了实现备注关于特性和条目结果的可伸缩性; 最后的社论清理.

(psa)

版本 1.6 (2004-05-11)

纠正了发布可用条目的例子; 更多澄清节点层次结构的性质.

(psa)

版本 1.5 (2004-05-10)

增加了澄清节点层次结构的备注.

(psa)

版本 1.4 (2004-05-07)

澄清 "directory"的用法; 增加章节定义一个实体和与它相关的条目之间的关系.

(psa)

版本 1.3 (2004-04-23)

更多澄清条目发布 item-publication 协议; 移除一些特性协商文本到 XEP-0020; 增加关于知名服务发现节点的注册项的信息; 增加关于遍历树和大结果集的实现备注; 附加了征集经验建议.

(psa)

版本 1.2 (2004-04-20)

社论清理; 附加了一些经验建议征集.

(psa)

版本 1.1 (2004-03-15)

以更正式的方式描述了需求, 语法, 和用例; 纠正了一些例子和schemas中的错误; 定义了 XMPP 登记处的程序; 增加了参考的号码; 定义了 XMPP 错误处理.

(psa)

版本 1.0 (2003-04-21)

通过Jabber理事会的投票, 提升状态为草案; 同时添加 XML schemas.

(psa)

版本 0.13 (2003-02-25)

增加了关于空节点的备注; 描述了关于多个 identity 元素的语义.

(pgm)

版本 0.12 (2003-02-06)

增加了对IQ-set的支持; 增加了关于 disco#info 到一个节点的例子.

(pgm)

版本 0.11 (2002-12-17)

根据标准列表里的讨论增加了对 'node' 属性的支持,以支持不可定址为JID的条目.

(psa)

版本 0.10 (2002-11-21)

修改了 <feature type='foo'/> 成为 <feature var='foo'/> 以跟踪特性协商的变化 (XEP-0020); 增加了初始的注册项参数.

(psa)

版本 0.9 (2002-11-07)

增加了 disco#item对空结果集的支持.

(psa)

版本 0.8 (2002-11-01)

对于item查询,移除了 max, start, 和 total 属性(这将由一个通用的分页协议来处理); 增加了 "http://jabber.org/protocol/feature-neg" 名字空间作为一个特性用于发出关于一个或多个特性的协商信号.

(psa)

版本 0.7 (2002-10-28)

清理特性文本和例子.

(psa)

版本 0.6 (2002-10-27)

增加了 'category' 属性到 <feature/> 元素; 增加了安全性, IANA, 和 XMPP 登记处 事项; 增加了例子的编号.

(psa)

版本 0.5 (2002-10-15)

全部翻修和简化

(psa)

版本 0.4 (2002-07-16)

重要补充和修正,更多的例子。

(psa)

版本 0.3 (2002-05-30)

围绕用例重新组织,做了一些小的修补。

(psa)

版本 0.2 (2002-05-05)

合并合著者的评论并增加备注.

(psa)

版本 0.1 (2002-05-03)

初始的草案.

(psa)

结束

个人工具