XMPP是一个开放式的XML协议,设计用于准实时消息和出席信息以及请求-响应服务。其基本的语法和语义最初主要是由Jabber开放源代码社区于1999年开发的。2002年,XMPP工作组被授权接手开发和改编Jabber协议以适应IETF的即时消息和出席信息技术。
概览
尽管XMPP没有指定任何特定的网络结构,但它通常是采用客户-服务器 架构进行实现,其中客户端通过TCP方式使用XMPP访问服务 器, 服务器之间也采用TCP方式进行通信。
以下是这一架构的抽象的示意图 (这里 "-" 表示使用 XMPP 通讯, "=" 表示可使用任何协议通讯)。
C1----S1---S2---C3
|
C2----+---G1===FN1===FC1
符号的含义如下:
· C1, C2, C3 = XMPP 客户端
· S1, S2 = XMPP 服务器
· G1 = 一个XMPP和外部(非XMPP)消息网络之间进行“翻译”的网关
· FN1 = 一个外部消息网络
· FC1 = 外部消息网络上的一个客户端
服务器
服务器充当xmpp通信的智能抽象层
· 对受验证的客户端,服务器以及其他实体之间以XML流形式的连接和会话进行管理。
· 在这些使用XML流的实体间对合理编址的XML节(第九章)进行路由
客户端
大部分客户端通过 TCP 连接直接连到服务器,并通过XMPP获得由服务器以及联合服务器所提供的全部功能。
建议的客户端和服务器连接的端口是 5222
网关
网关是一个特殊用途的服务器端的服务,主要功能是把 XMPP 翻译成外部(非XMPP)消息系统,并把返回的消息翻译成 XMPP
网络
因为每个服务器都是由一个网络地址来标识的并且服务器之间的通信是 客户-服务器 协议的直接扩展,实际上整个系统是由很多互通的服务器构成的。建议的(RECOMMENDED)服务器之间的连接端口为 5269
地址空间
概览
一个实体可以是任何一个被认为是一个网络端点的东西(例如网络上的一个 ID ),而且它是通过XMPP进行通信的。所有这些实体都有一个具有唯一性的地址,并符合 RFC 2396 [URI]规范要求的格式。由于历史原因,一个 XMPP 实体的地址被称为 Jabber Identifier 或 JID 。一个合法的 JID 包括一组排列好的元素,包括域名(domain identifier),节点名(node identifier),和资源名(resource identifier)。
jid = [ node "@" ] domain [ "/" resource ]
domain = fqdn / address-literal
fqdn = (sub-domain 1*("." sub-domain))
sub-domain = (internationalized domain label)
address-literal = IPv4address / IPv6address
所有 JID 都是基于上述的结构。类似 <user@host/resource> 这种结构,最常用来标识一个即时消息用户,这个用户所连接的服务器,以及这个用户用于连接的资源(比如特定类型的客户端软件)。
域名是一个主要的ID并且是 JID 中唯一必需(REQUIRED)的元素(一个纯粹的域名也是一个合法的 JID)。
节点名是一个可选(OPTIONAL)的第二 ID,放在域名之前并用符号"@"分开.它通常表示一个向服务器或网关请求和使用网络服务的实体(比如一个客户端),当然它也能够表示其他的实体(比如在多用户聊天系统中的一个房间). 节点名所代表的实体,它的地址依赖于一个特定的域名;在 XMPP 的即时消息和出席信息应用系统中,这个地址是“纯 JID” <node@domain> 中的一部分。
资源名是一个可选的第三 ID,它放在域名的后面并由符号"/"分开。资源名可以跟在 <node@domain>后面也可以跟在 <domain> 后面。它通常表示一个特定的会话,连接(比如设备或者所在位置),或者一个附属于某个节点ID实体相关实体的对象(比如多用户聊天室中的一个参加者)。对于服务器和和其他客户端来说,资源名是不透明的。
XML流
概览
两个基本概念,XML流和XML节,使得在出席信息已知的实体之间,异步交换低负载的结构化信息成为可能。
XML流的定义:一个XML流是一个容器,包含了两个实体之间通过网络交换的XML元素。一个XML流是由一个XML打开标签 <stream> (包含适当的属性和名字空间声明)开始的,流的结尾则是一个XML关闭L标签 </stream>
XML节的定义: 一个XML节是一个实体通过 XML 流向另一个实体发送的结构化信息中的一个离散的语义单位。一个XML节直接存在于根元素<stream/>的下一级,这样可以说是很好的匹配了[XML](译者注:在标准参考一节)的第43条.任何XML节都是从一个XML流的下一级的某个打开标签(如 <presence>)开始,到相应的关闭标签(如 </presence>)。
客户端和服务器会话的例子。为了连接一个服务器,一个客户端必须(MUST)发送一个打开标签<stream>给服务器,初始化一个XML流,也可选择(OPTIONAL)在这之前发送一段文本声明XML版本和支持的字符集(参见文本声明的内容(第十一章第四节); 也可看字符编码(第十一章第五节))。视本地化策略和提供的服务而定,服务器应该(SHOULD)回复一个XML流给客户端,同样的,也可选择在这之前发送一段文本声明。一旦客户端完成了SASL握手(第六章),客户端可以(MAY)通过流发送不限量的XML节给网络中的任何接收者。当客户端想关闭这个流,它只需要简单的发送一个关闭标签</stream>给服务器(或者作为另一个选择,可能由服务器关闭这个流)。然后,客户端和服务器都应该(SHOULD)彻底地终止这个连接(通常是一个TCP连接)。
stream 属性
stream 元素的属性如下:
· to -- 'to' 属性应(SHOULD)仅出现在初始化实体发给接收实体的 XML 流的头当中,并且它的值必须(MUST)是接收实体所在的主机名。在接收实体发送给初始化实体的 XML 流的头中不应该(SHOULD NOT)出现 'to' 属性。若 'to' 属性出现在应答流中,则初始化实体应(SHOULD)忽略它。
· from -- 'from' 属性应(SHOULD)仅出现在接收实体发给初始化实体的 XML 流的头当中,并且它的值必须(MUST)是为当前初始化实体授权的接收实体所在的主机名。注意,不应该(SHOULD NOT)有 'from'属性出现在初始实体发送给接收实体的 XML流的头中;无论如何,如果'from'属性出现在初始化流中,接收实体应该(SHOULD)忽略它。
· id -- 'id'属性应该(SHOULD)仅用于接收实体发送给初始化实体 XML流的头。这个属性是一个由接收实体创建的具有唯一性的ID,一个初始实体和接收实体之间的会话ID,并且它在接收方的应用程序中(通常是一个服务器)必须(MUST)是唯一的。注意,这个流 ID 必须是足够安全的,所以它必须是不可预知的和不可重复的(参见[RANDOM] 了解如何获得随机性以保证安全性)。不应该(SHOULD NOT)有 'id'属性出现在初始实体发送给接收实体的 XML流的头中;无论如何,如果'id'属性出现在初始化流中,接收实体应该(SHOULD)忽略它。
· xml:lang -- 'xml:lang'属性(定义在/[XML/]中的第二章第十二节)应该(SHOULD)包含在初始化发给接收实体的 XML流的头中,以指定在流中传输的可读XML字符所使用的缺省语言。如果这个属性出现了,接收实体应该(SHOULD)记住它的值,作为初始化流和应答流的缺省属性;如果这个属性没有出现,接收实体应该(SHOULD)用一个可配置的缺省值用于双方的流,这个属性值必须(MUST)在应答流的头中传达。对于所有初始化流中传输的节,如果初始实体没有提供'xml:lang'属性,接收实体应该(SHOULD)应用缺省值;如果初始实体提供了'xml:lang'属性,接收实体不能(MUST NOT)修改或删除它(参见第九章第一节第五小节 xml:lang)。'xml:lang'属性的值必须(MUST)是一个 NMTOKEN (定义在/[XML/]的第二章第三节) 并且必须(MUST)遵守 RFC 3066 /[LANGTAGS/] 规定的格式。
· version -- version属性
流错误
流的根元素可以(MAY)包含一个 <error/> 子元素,由流的名字空间前缀作为它的前缀。这个"错误"子元素必须(MUST)由感知到发生了流级别错误的实体发送(通常是一个服务器而不是一个客户端)。
Xml节
基本语义学
消息语义学
<message/>节类型可以被看作是一个"push"机制用于一个实体推送信息给另一个实体,类似发生在email系统中的通信. 所有消息节应该(SHOULD)处理一个表明预定的消息接收者的'to'属性;接收了这样一个节之后,一个服务器应该(SHOULD)路由或递送它给预定的接收者(见 Server Rules for Handling XML Stanzas (第十章)的XML节相关的通用路由和递送规则).
出席信息语义学
<presence/> 元素可以被看作一个基本的广播或“出版-订阅”机制,用于多个实体接收某个已订阅的实体的信息(在这里,是网络可用性信息). 通常,一个发行实体应该(SHOULD)不带'to'属性发送一个出席信息,这时这个实体所连接的服务器应该(SHOULD)广播或多播(multiplex?)那个节给所有订阅的实体.无论如何,一个发行实体也可以(MAY)带'to'属性发送一个出席信息节,这时服务器应该(SHOULD)路由或递送这个节给预定的接收者.见 Server Rules for Handling XML Stanzas (第十章)的XML节相关的通用路由和递送规则,以及[XMPP-IM|XMPP文档列表/XMPP正式RFC标准/RFC3921]中即时消息和出席信息应用中出席信息的特定规则.
IQ语义学
信息/查询(Info/Query),或曰IQ,是一个 请求-回应 机制,某些情况下类似/[HTTP/].IQ语义学使一个实体能够向另一个实体做出请求并做出应答. 请求和应答所包含的数据定义在IQ元素的一个直接的子元素的名字空间声明中, 并且由请求实体用'id'属性来跟踪这一交互行为. 因而,IQ交互伴随着一个结构化的数据交换的通用模式例如 get/result 或 set/result (尽管有时候会以一个错误信息应答某个请求):
为了强制执行这些语义学,要应用以下规则:
1. 对于IQ节来说'id'属性是必需的(REQUIRED).
2. 对于IQ节来说'type'属性是必需的(REQUIRED). 它的值必须(MUST)是以下之一:
· get -- 这个节是一个对信息或需求的请求.
· set -- 这个节提供需要的数据, 设置新的值, 或取代现有的值.
· result -- 这个节是一个对一个成功的 get 或 set 请求的应答.
· error -- 发生了一个错误,关于处理或递送上次发送的 get 或 set的(参见 节错误 Stanza Errors(第九章第三节)).
3. 一个接收到"get" 或 "set" 类型的IQ请求的实体必须(MUST)回复一个"result"或"error"类型的IQ应答(这个应答必须(MUST)保留相关请求的'id'属性).
4. 一个接收到"result"或"error"类型的IQ节的实体不能(MUST NOT)再发送更多的"result"或"error"类型的IQ应答; 无论如何, 如上所述, 请求实体可以(MAY)发送另一个请求(如, 一个"set"类型的IQ,通过get/result对提供查询(discovery)所需的信息).
5. 一个"get" 或 "set" 类型的IQ节必须(MUST)包含并只包含一个子元素指明特定请求或应答的语义.
6. 一个"result"类型的IQ节必须(MUST)包含零或一个子元素.
7. 一个"error"类型的IQ节应该(SHOULD)包含和"get"或"set"相关联的那个子元素并且必须(MUST)包含一个<error/>子元素;详细信息,见Stanza Errors (第九章第三节).
摘自http://wiki.jabbercn.org/index.php?title=RFC3920&variant=zh-cn#.E6.A6.82.E8.A7.88_3