两个XMPP实体交互的过程是这样的:打开一个TCP连接,TCP上建立一个XML Stream,协商一些安全机制和功能在,之后双方就
可以通过互相发送XML节来交换信息。XMPP是一种多用途的通用协议,并不只用于聊天应用。针对各种不同的功能,由不同的XEP
定义了相应的规范,这些规范简单的来说就是定义了与该功能相关的XML节的交换顺序、具体的格式。
XML Stream和XML Stanza是XMPP中两个很重要的概念。
一个XML Stream是一个容器,承载网络任意两个实体间交换的XML元素。说容器有点不太恰当,应该说是一个通道。类似于两个打电
话的人,拨通之后,就会在两个手机之间建立一条专门的通道,2人就可以开始通话了。XML Stream被明确定义为以一个开"stream header"开始.(例如:一个带有合适属性和命名空间生命的XML<stream> 标记)。在流的生命周期内,发起流的一方可以通过流发送任意
数量的XML元素,包括用于协商流的元素和其它XML节。要注意流是单向的,通信双方都需要向对方发起一个流。“initial stream"是由
初始实体向接受实体发起的,接受实体要在相反的方向向初始实体发起流协商("response stream")。
XML 节是XMPP中有意义的基本单元。一个XML节必须满足两个条件,一是它的元素名是这三者之一:"message", "presence", "IQ" ,而是命名空间是"jabber:client" or "jabber-server"。否则不属于XML Stanza,比如stream errors, stream features, TLS-related 元素, SASL-related 元素等。一个XML节根据需要一般会包含一个或多个子元素,子元素表面了想要传达的信息。
XMPP定义了3中基本的节:message, presence, IQ。这些节提供了不同的通信原语:一般消息的“推送”机制,用于广播网络可用性
的“发布-订阅”机制,“请求/响应”机制,用于交换更多的结构化数据。
+--------------------+--------------------+ | INITIAL STREAM | RESPONSE STREAM | +--------------------+--------------------+ | <stream> | | |--------------------|--------------------| | | <stream> | |--------------------|--------------------| | <presence> | | | <show/> | | | </presence> | | |--------------------|--------------------| | <message to='foo'> | | | <body/> | | | </message> | | |--------------------|--------------------| | <iq to='bar' | | | type='get'> | | | <query/> | | | </iq> | | |--------------------|--------------------| | | <iq from='bar' | | | type='result'> | | | <query/> | | | </iq> | |--------------------|--------------------| | [ ... ] | | |--------------------|--------------------| | | [ ... ] | |--------------------|--------------------| | </stream> | | |--------------------|--------------------| | | </stream> | +--------------------+--------------------+
A Simplistic View of Two Streams |
从另一个角度来讲,这两个流相当于两份XML文档,根元素<stream/>相当于XML文档的实体,通过流发送的XML节相当于文档片段。
from: from属性指定发送stream元素的实体的XMPP标识,一般是一个JID
I: <?xml version='1.0'?> <stream:stream from='[email protected]' to='im.example.com' version='1.0' xml:lang='en' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
I: <?xml version='1.0'?> <stream:stream from='example.net' to='im.example.com' version='1.0' xml:lang='en' xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams'>
to: 预期接收者的XMPP标识
id: id属性指定了流的唯一标识,称之为“Stream ID". Stream ID 只能由接收实体产生,在它发送流响应包时必须包含该属性。在初始流头部中,初始实体不应该指定id属性;然而,如果指定了,接收实体必须忽略它。
接收实体必须在响应流头部中包含id属性。
xml:lang: 指定通过流发送的XML字符数据的语言。
I: <?xml version='1.0'?> <stream:stream from='[email protected]' to='im.example.com' version='1.0' xml:lang='en' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
version: 版本信息,一般设为1.0
+----------+--------------------------+-------------------------+ | | initiating to receiving | receiving to initiating | +----------+--------------------------+-------------------------+ | to | JID of receiver | JID of initiator | | from | JID of initiator | JID of receiver | | id | ignored | stream identifier | | xml:lang | default language | default language | | version | XMPP 1.0+ supported | XMPP 1.0+ supported | +----------+--------------------------+-------------------------+
一个XML命名空间由一个URL引用标识。命名空间提供了避免元素命名冲突的方法。
XML 命名空间属性被放置于元素的开始标签之中,并使用以下的语法:
xmlns:namespace-prefix="namespaceURI"
当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。
注释:用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。