`

Jabber 协议 概述(2)

    博客分类:
  • XMPP
阅读更多

6.19. jabber:x:encrypted——加密消息
    加密消息名字空间用来支持使用公共密钥(一般通过客户端使用PGP或GPG,服务端用同样的名字空间进行加密来实现)加密的消息交互。一个相关的名字空间,jabber:x:signed,用来进行当前状态信息的加密。
    例子:
 
<message from=’juliet@capulet.com/balcony’ to=’romeo@montague.net/orchard’>
<body>This Message is Encrypted</body>
<x xmlns=’jabber:x:encrypted’>
hQEOA7ucqu53AhlPEAP/ZbU6oPnRAbIcUxMK1XRVnkgZ/Agtq1tcTQuEZxbpZLl4
C/4psQGLgBU5h5Y3/khxtJTPXKn1izyc+DRZ8hqn2p4mwC8ioKTBJ6P6dfEpQEyt
a4bimM5fqdeh4gRkMhwThRSJxBCJBVVWFEViu+0KlHHB5AeeL4qwRGb2dhGjIgQD
/R9x0D0qtgBGwf/TVnRGZYRX7epxCNuNDEYKZSs4LEoTPL8CVsAWOzS2QgS0GBqt
tFDKId6XaNu36dB2D8VHdxQnI8RtHo9pfTYDaXWB3dMGTt896iEO/sTuucYObf3s
K5Kygg0uWpBpvQPj8Y041FhnUBz8DRGCnuFLQxCI6ch4ybauXfOKNOGDQwmsnJZm
6OaeVFUwdsedI3c6VdQtodnWVutckR5BOjnn0VqnhrVTu7cp6VXrrRK4g9atPEe6
C4R/MilBjzIJBcET0jhWuAyiBo3gN/6IqYRZNSXL9ZqGPJwNTlYim1EHN3qBqiUw
zUMamEoRzcusn80Z7kylve5ujIeSD/pVwoawHHvLp92kO2hd0yGD0UrWSfKU1o6y
EY8yhZ5P1v02pIKigAUI2c6LTDxt/KhSxQ==
=fijN
</x>
</message>
6.20. jabber:x:envelope——消息信封
    消息信封名字空间是表明消息有更多的寻址方式,如联合email进行的寻址。下面是一些所支持的名字空间:
l           to
l           cc
l           replyto
l           from
l           forwardedby
上述每一个元素都带有一个”jid”属性来标识Jabber实体是发送、中转、还是收到消息。
例子:
 
<message from=’juliet@capulet.com/tomb’ to=’romeo@montague.net/tomb’>
<body>And there I am. Where is my Romeo?</body>
<x xmlns=’jabber:x:envelope’>
<to jid=’romeo@heaven.org>Romeo</to>
<forwardedby jid=’root@heaven.org>God</forwardedby>
</x>
</message>
6.21. jabber:x:event——消息事件
    消息时间名字空间是标识一条消息的状态的一个机制。现在,事件与一条消息如下般相关联:
l           <composing/>——个用户正在对消息进行回复
l           <delivered/>——发送给指定接收者的消息
l           <displayed/>——显示给指定接收者的消息
l           <offline/>——为离线进行存储的消息
对于客户端来说,这些消息事件的支持是可选的,而且,只有在另一用户在聊天中发出请求,这些消息事件才会被发送。不同的Jabber客户端将对当前状态消息事件进行不同的显示。
对消息通知的请求的例子:
 
<message
from="juliet@capulet.com/balcony"
to="romeo@montague.net/orchard"
id="1001">
<body>By whose direction found’st thou out this place?</body>
<x xmlns="jabber:x:event">
<composing/>
</x>
</message>
 
发送消息通知的例子:
 
<message from="romeo@montague.net/orchard" to="juliet@capulet.com/balcony">
<body>By whose direction found’st thou out this place?</body>
<x xmlns="jabber:x:event">
<composing/>
<id>1001<id/>
</x>
</message>
 
    可以同时请求多个消息事件。
6.22. jabber:x:expire——消息到期
    消息到期名字空间是说明一条消息拥有一个有限的存活事件的一个简单扩展。如果消息被离线存储,而到了到期时间,服务器将不再发送该消息。如果一条消息为预览就进行发送,Jabber客户端可以选择不显示该消息。“secondes”属性定义消息发送的事件。
    例子:
 
<message from="sailor@denmark.com" to="horatio@denmark.com">
<body>There’s a letter for you sir</body>
<x xmlns="jabber:x:expire" seconds="3600"/>
</message>
 
6.23. jabber:x:oob——绑定数据输出
    绑定数据输出名字空间使用户可以通过交换一个标准的URL来实现文件传输的目电。使用jabber:x:oob的URLs交换可以包含任一消息(在一个<x/>子元素内),感觉就像email里的附件一样。多个附件可以包含在同一个消息中。
    例子:
 
<message from="sailor@denmark.com" to="horatio@denmark.com">
<body>URL Attached.</body>
<x xmlns="jabber:x:oob">
<url>http://denmark.com/act4/letter-1.html</url>
<desc>There’s a letter for you sir</desc>
</x>
</message>
6.24. jabber:x:roster——内置的花名册条目
    内置的花名册条目使用户可以在一个消息中包含花名册条目,这样很容易在用户之间发送联系方式。每一个花名册条目都包含在一个<x/>的一个<item/>子元素中。这个<x/>元素一般用在一个<message/>元素中,但这不是必须的。
    例子:
 
<message to="hamlet@denmark.com">
<body>
Here are some new Jabber users
to add to your contact list!
</body>
<x xmlns="jabber:x:roster">
<item jid="claudius@denmark.com" name="King">
<group>Royalty</group>
</item>
<item jid="horatio@denmark.com" name="Horatio">
<group>Friends</group>
</item>
<item jid="fortinbras@norway" name="Prince Fortinbras"/>
</x>
</message>
6.25. jabber:x:signed——有符号的当前状态
    有符号的当前状态名字空间用来支持交换使用公共密钥(客户端使用PGP或GPG,服务端使用同样的名字空间进行加密)加密的当前状态信息。一个相关的名字空间,jabber:x:encrypted用来支持加密消息。
    例子:
 
<presence from=’juliet@capulet.com/balcony’ to=’romeo@montague.net/orchard’>
<show>away</show>
<status>be back later</status>
<x xmlns=’jabber:x:signed’>
iD8DBQA6kasv0xpc2/POfPkRAnz0AJ9UEYYWWSReddIKk3AYMfTFtqQDJwCfbcLd
JcSUOR0FlS+rDFjAPaSMgSM+iNaNm
</x>
</presence>
6.26. vcard-temp——临时vCard
    vCard格式是一个“电子商务卡的标准格式,通过使用通过互联网进行个人数据的直接交换,如同在非互联网下的环境一样”。由于XML的vCard的格式还没有标准化,Jabber.org项目在XML的vCard标准建立之前,暂时设置了这样一个临时名字文件。由于这几年在vCard的XML的官方标准的指定上没有任何进步,Jabber.org开发者专门为这个项目创建了一个项目吸引Jabber社区外其它开发者的注意。因此,最后的XML的vCard格式的最后DTD可能会在下面的URL中找到:
http://www.vcard-xml.org/
   
    例子1(对vCard的客户端请求):
 
<iq type="get">
<vCard xmlns="vcard-temp"/>
</iq>
 
    例子2(客户端收到vCard数据):
 
<iq type="result">
<vCard version="3.0" xmlns="vcard-temp">
vCard data goes here
</vCard>
</iq>
 
    例子3(客户端向服务端发送vCard):
<iq type="set">
<vCard version="3.0">
vCard data goes here
</vCard>
</iq>
7. 使用用例
    这一部分提供一些在Jabber协议上略有不同的观点,通过用例来阐述。下面每一个例子都展示一个Jabber用户完成一个完整的任务的消息流程,该流程包括接收和发送,如注册到一台服务器,登陆,改变当前状态,或者发送一条消息。如果时间允许,我将把这部分引申的更远。
7.1. Jabber用户注册
    本用例同时邪显示Jabber用户向服务器开启一个socket的连接,以及服务器的响应(如:<stream:stream>标签)。
1.    Jabber用户通过开启一个从客户端到服务器端的XML流,来申请一个在服务器上的socket连接。
 
SEND: <stream:stream
to=’capulet.com’
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’>
 
2.    服务器通过开启一个从服务器到客户端的XML流进行回复。
 
RECV: <stream:stream
from=’capulet.com’
id=’180763465’
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’>
 
3.    Jabber用户提供一个需要注册一个帐号(理论上,这需要一个不同的顺序:首先询问服务器需要什么信息,然后服务器器告知客户端需要什么样的信息;但在实际中,假定需要的信息是:用户名,资源,密码)的信息。
 
SEND:  <iq id=’1’ type=’set’>
           <query xmlns=’jabber:iq:register’>
               <username>Juliet</username>
               <resource>balcony</resource>
           </query>
        </iq>
 
4.    服务器响应一个空的类型为”result”的iq元素,表示注册已成功。
 
RECV:   <iq id=’1’ type=’result’/>
7.2. Jabber用戶登陆
1.     Jabber用户询问服务器,登陆所需要提供的信息。
 
SEND: <iq id=’2’ type=’get’>
           <query xmlns=’jabber:iq:auth’>
              <username>Juliet</username>
           </query>
       </iq>
 
2.     服务器提示Jabber用户登陆所需要的信息。
 
RECV: <iq id=’2’ type=’result’>
           <query xmlns=’jabber:iq:auth’>
              <username>Juliet</username>
              <password/>
              <digest/>
              <sequence>500<sequence/>
              <token>3B905BFD</token>
              <resource/>
           </query>
       </iq>
 
3.     Jabber用户提供所需的信息——在本例中,是一个<hash/>元素,它是对信息进行一个零度知识认证的一个哈希。(详情请见http://docs.jabber.org/draft-proto/html/zerok.html)。
 
SEND: <iq id=’3’ type=’set’>
           <query xmlns=’jabber:iq:auth’>
              <username>Juliet</username>
              <resource>balcony</resource>
                          <hash>77d7eacde5e56b9622d0a075cb88361b110f
b9d7</hash>
                     </query>
                  </iq>
 
4.     服务器响应一个空的类型为”result”的iq元素,表明登陆成功。
 
RECV: <iq id=’3’ type=’result’/>
 
5.     Jabber用户发送当前状态给服务器,表明其在线。
 
SEND: <presence>
           <status>Online</status>
       </presence>
7.3. Jabber用户增加一个联系人
1.     Jabber客户端在花名册上增加一个联系人(只是预备的操作)。
 
SEND: <iq type=’set’>
           <query xmlns=’jabber:iq:roster’>
              <item jid=’romeo@montague.net’
Name=’remeo’/>
                     </query>
                  </iq>
 
2.     Jabber用户发送一个对该联系人的订阅请求。
 
SEND: <presence to’remeo@montague.net’ type=’subscribe’>
           <status>Wherefore are thou?</status>
       </presence>
 
3.     服务器发送一个花名单推送给用户一个新条目和一个类型为”none”的订阅(早已有了该订阅)。
 
RECV: <iq type=’set’>
           <query xmlns=’jabber:iq:roster’>
              <item jid=’romeo@montague.net’
name=’romeo’
subscription=’none’/>
                     </query>
                  </iq>
 
4.     服务器发送一个类型为”result”的iq包,表示花名册推送成功(让人有点疑惑的是,这个包是从Jabber用户发送到Jabber用户的!)
 
RECV: <iq
from=’juliet@capulet.com/balcony’
to=’julie@capulet.com/balcony’
type=’result’>
 
5.     服务器发送另一个花名单推送,这次是ask=’subscribe’属性,表示订阅的状态未定。
 
RECV: <iq type=’set’>
           <query xmlns=’jabber:iq:roster’>
              <item
ask=’subscribe’
jid=’romeo@montague.net’
name=’romeo’
subscription=’none’/>
                     </query>
                  </iq>
 
6.     Romeo对订阅请求的下一个响应会是什么呢?现在我们假定订阅以Romeo接受订阅请求为“结束”的。
 
RECV: <presence
from=’romeo@montague.net’
to=’juliet@capulet.com’
type=’subscribed’/>
 
7.     服务器再次发送一个花名单推送给客户端,这次subscription=’to’,表示订阅请求被接受了(Juliet现在可以订阅到Romeo的当前状态了)。
 
RECV: <iq type=’set’>
           <query xmlns=’jabber:iq:roster’>
              <item
jid=’romeo@montague.net’
name=’romeo’
subscription=’to’/>
                     </query>
                  </iq>
7.4. Jabber用户获得花名册
           SEND: <iq type=’get’>
                     <query xmlns=’jabber:iq:roster’/>
                  </iq>
 
RECV:<iq from=’juliet@capulet.com/balcony’ type=’result’>    
                     <query xmlns=’jabber:iq:roster’>
                         <item
jid=’romeo@montague.net’
name=’romeo’
subscription=’both’/>
                     </query>
                  </iq>
7.5. Jabber用户发送一条消息
           SEND: <message to’romeo@montague.net’>
                     <body>Wherefore are thou?</body>
                  </message>
    注意:服务器会根据Jabber用户的会话信息加上一个源地址,这样接收者收到消息时,消息中已经包含了源地址。
7.6. Jabber用户改变当前状态
       SEND: <presence>
                  <status>stepped away…</status>
                  <show>away</show>
              </presence>
7.7. Jabber用户登出
    登出时很容易的,只需要关闭<stream>……
 
       SEND: </stream:stream>
       RECV: </stream:stream>
8. 参考文献
    本协议参考以下文献
l           Jabber开发指南(http://docs.jabber.org/jpg/
l           Jabber协议――标准(http://docs.jabber.org/proto/
l           Jabber协议――草案(http://docs.jabber.org/draft-proto/
l           Romeo and Juliet
(http://tech-two.mit.edu/Shakespeare/Tragedy/romoandjuliet/full.html)
9. 结束语
    本文档提供了一个关于Jabber的XML协议的一个详细的怪数。如果你对本文档有任何问题,请通过email或Jabber的方式自由地与作者联系(Peter Saint-Andre),他的帐号时stpeter@jabber.org
10. 版权信息
This document is copyright 2001 by Peter Saint-Andre.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License (http://www.gnu.org/copyleft/fdl.html),
Version 1.1 or any later version published by the Free Software Foundation, with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. You may obtain a
copy of the GNU Free Documentation License from the Free Software Foundation by
visiting http://www.fsf.org/ or by writing to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA02111-1307
USA
附录 A 标准错误代码
    下面是Jabber中错误代码的一些简要描述。Jabber服务器在碰到不同的错误条件下生成这些错误代码。一般Jabber错误代码以HTTP规格的RFC 2616(http://www.ietf.org/rfc/rfc2616.txt)为基础。但Jabber没有使用所有的HTTP的错误代码,并且Jabber错误代码与HTTP错误代码相对应时,通常只有Jabber自己的含义。注意本附录只包含Jabber服务器生成的错误代码,而不包括服务器端组件如网关发到外部消息系统。
 
错误代码 描述 注意
302 重定向 尽管HTTP规定中包含八种不同代码来表示重定向,Jabber只用了其中一个(用来代替所有的重定向错误)。不过Jabber代码302是为以后的功能预留的,目前还没有用到
400 坏请求 Jabber代码400用来通知Jabber客户端,一个请求因为其糟糕的语法不能被识别。例如,当一个Jabber客户端发送一个的订阅请求给它自己活发送一条没有包含“to”属性的消息,Jabber代码400就会产生。
401 未授权的 Jabber代码401用来通知Jabber客户端它们提供的是错误的认证信息,如,在登陆一个Jabber服务器时使用一个错误的密码,或未知的用户名。
402 所需的费用 Jabber代码402为未来使用进行保留,目前还不用到。
403 禁止 Jabber代码403被Jabber服务器用来通知Jabber客户端该客户端的请求可以识别,但服务器拒绝执行。目前只用在注册过程中的密码存储失败。
404 没有找到 Jabber代码404用来表明Jabber服务器找不到任何与JabberID匹配的内容,该JabberID是一个Jabber客户端发送消息的目的地。如,一个用户打算向一个不存在的JabberID发送一条消息。如果接受者的Jabber服务器无法到达,将发送一个来自500级数的错误代码。
405 不允许的 Jabber代码405用在不允许操作被’from’地址标识的JabberID。例如,它可能产生在,一个非管理员用户试图在服务器上发送一条管理员级别的消息,或者一个用户试图发送一台Jabber服务器的时间或版本,或者发送一个不同的JabberID的vCard。
406 不被接受的 Jabber代码406用于服务器因为某些理由不接受一个包。例如,这个可能发生在,一个Jabber客户端试图使用jabber:iq:private在服务器上存储信息,但当前的用于存储的名字空间用”jabber:”开头(在Jabber里是一个被存的XML开头)。另一种可能产生406错误的情况是当一个Jabber客户端试图用一个空密码注册到一台Jabber服务器上。
407 必须注册 Jabber代码407当前不被使用
408 注册超时 当一个Jabber客户端不能在服务器准备好的时间内发起一个请求时,Jabber服务器生成Jabber代码408。这个代码当前只用于Jabber会话管理器使用的零度认证模式中。
409 冲突 略
500 服务器内部错误 当一台Jabber服务器遇到一种预期外的条件,该条件阻止服务器处理来自Jabber客户端的包,这是将用到Jabber代码500。现在,唯一会引发500错误代码的时间是当一个Jabber客户端试图通过服务器认证,而该认证因为某些原因没有被处理(如无法保存密码)。
501 不可执行 当服务器不支持Jabber客户端请求的功能,使用Jabber代码501。例如,该代码只当Jabber客户端发送一个认证请求,而该认证请求不包含服务器配置中定义的任何一种认证方式时,服务器发送Jabber代码501。这个代码还被用于,当一个Jabber客户端试图注册一个不允许注册的服务器。
502 远程服务器错误 当因为无法到达远程服务器导致转发一个包失败时,使用Jabber代码502。该代码发送的特殊例子包括一个远程服务器的连接的失败,无法获取远程服务器的主机名,以及远程服务器错误导致的外部时间过期。
503 服务无法获得 当一个Jabber客户端请求一个服务,而Jabber服务器通常由于一些临时原因无法提供该服务时,使用Jabber代码503。例如,一个Jabber客户端试图发送一条消息给另一个用户,该用户不在线,但它的服务器不提供离线存储服务,服务器将返回一个503错误代码给发送消息的JabberID。当为vcard-temp和jabber:iq:private名字空间设置信息时,出现通过xdb进行数据存储的写入错误,也使用该代码。
504 远程服务器超时 Jabber代码504用于下列情况:试图连接一台服务器发生超时,错误的服务器名。
510 连接失败 Jabber代码510目前还没有使用。

 


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics