- 浏览: 348058 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
pacoson:
感谢楼主。请受小生一拜。
ANT预编译JSP -
zhuhongming123:
一楼的同学Lucene4.* 以上的 已经改成了Numeric ...
Lucene日期排序及组合查询 -
ywjk520:
RangeQuery在哪个包里?
Lucene日期排序及组合查询 -
willwen:
有个疑问,楼主,为何初始化bits 从txt读取已有的网址是直 ...
布隆过滤器(Bloom Filter)之java实例 -
yu_226528:
还不如没有呢
jFreeChart 在jsp页上实现简单的折线图、柱状图
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目前还没有使用。
发表评论
-
基于 XMPP协议的即时消息服务端简单实现
2010-01-27 11:43 1038服务器端XmppSeverConnection类事件 / ... -
基于XMPP协议的即时通讯工具的服务器端实现
2010-01-27 11:15 1452基于XMPP协议的即时通讯 ... -
基于 XMPP协议的服务器端 文件互传的简单实现
2010-01-27 11:11 1817学习一下基于XMPP协议的文件传输,首先假设用户已经登录, ... -
Instant Messaging java(2)
2010-01-27 10:17 868IM概念和Jabber协议从现 ... -
Instant Messaging java(1)
2010-01-27 10:12 9701.Jabber包怎么路由 理解Jabber路由计划的关键是 ... -
Jabber核心协议(XMPP Core :RFC3920)
2010-01-27 09:32 19111、 /XML StanzaXML StreamStream ... -
Jabber 协议 概述(1)
2010-01-27 09:21 12111. 介绍 Jabber是一个由开源社区发起并领导开发的 ...
相关推荐
**Jabber协议概述** Jabber协议,全称为Extensible Messaging and Presence Protocol(XMPP),是一种基于XML的即时通信协议。它最初由Jabber开源社区开发,并在2002年被互联网工程任务组(IETF)采纳为RFC 3920和...
**二、Jabber协议的三大基石:XML元素** Jabber协议的构建基于三个关键的XML元素: 1. **** —— 用于承载两个Jabber用户间或两个JabberID之间的消息内容,无论是文本、图片还是其他媒体,都可通过此元素进行传输...
Jabber(XMPP)服务协议的概述中文版
Jabber协议主要由三个顶级XML元素构成:、和(info/query),每个元素都承载了大量的数据并通过特定的属性和命名空间来描述信息的具体内容。这些元素是Jabber协议的基础,也是实现即时通讯的关键所在。 ##### 2.1 ...
### Jabber/XMPP技术概述 Jabber/XMPP(eXtensible Messaging and Presence Protocol)是一种基于XML的即时消息传递和在线状态服务协议。它最初由Jabber开发,后被IETF采纳为正式标准。该协议的核心优势在于其开放...
##### 2.2 Jabber协议概述 Jabber协议是一种开放式的即时消息协议,支持多种消息格式和扩展特性。它采用XML作为消息传递的标准格式,并利用XMPP(Extensible Messaging and Presence Protocol)作为核心协议栈,...
Cisco Jabber SIP URI呼叫概述 文档介绍的是Cisco Jabber客户端通过移动远程访问(Mobile Remote Access, MRA)实现与不同组织的用户进行SIP URI呼叫的配置过程。该过程涉及到Cisco统一通信管理器(Cisco Unified ...
二、XMPP协议概述 XMPP是一种基于XML的开放标准协议,用于即时消息传递和在线状态管理。它以分散式架构设计,具有良好的可扩展性和安全性,被广泛应用于企业级通讯系统和各种IM应用中。JABBER是XMPP的一个早期实现,...
4. **开放标准**:Jabber是基于开放标准XMPP(Extensible Messaging and Presence Protocol)开发的,这意味着任何人都可以自由地开发客户端和服务端软件来支持Jabber协议。 5. **跨平台兼容性**:由于其开放标准和...
1. **Jabber协议概述** Jabber协议是一种开放的XML协议,它与传统的即时通讯系统不同,因为它允许第三方开发者创建扩展以满足特定需求。协议包括三个顶级XML元素:`<message/>`, `<presence/>`, 和 `<iq/>`(info/...
**JabberClient 开源项目概述** JabberClient 是一个基于 .NET Compact Framework 的开源项目,使用 C# 语言编写。它旨在为 Windows PC 和 Windows Mobile PDA 平台提供一个功能丰富的 Jabber 即时通讯客户端。...
1. **概述**:RFC3920详细介绍了可扩展消息和出席信息协议(XMPP)的核心功能,该协议通过XML流实现在任意两个网络终端之间进行接近实时的结构化信息交换。XMPP提供了通用的、可扩展的框架,主要用于即时消息和出席...
`Jabber.py` 是一个专为 Python2 设计的开源库,用于构建和扩展即时通讯(Instant Messaging,IM)应用,特别是在 Jabber 协议上运行的服务。Jabber 是一种基于 XML 的开放即时通讯协议,现在通常被称为 Extensible ...
通过使用Jabber协议,系统能够实现实时消息传输、好友列表管理、状态更新等功能。此外,为了确保系统的可维护性和可扩展性,采用了软件工程的开发模式,并利用统一建模语言(UML)进行了详细的系统建模。 #### 三、...
该协议最初由Jabber开源社区在1999年开发,后被IETF(Internet Engineering Task Force)采纳并进一步发展。XMPP的核心功能定义在RFC3920中,主要面向即时消息和出席信息应用,并遵循RFC2779的需求。 #### 二、通用...
文档首先介绍了XMPP的概述,指出它起源于Jabber开源社区,后经IETF的XMPP工作组进一步发展,定义了XMPP 1.0的核心功能。XMPP协议的关键字遵循RFC 2119中的规定,如"MUST"、"SHOULD"等,具有明确的规范意义。 在通用...
1. Xmpp协议概述:XMPP是一种用于即时消息和在线状态信息的开放标准通信协议,它让不同的网络服务可以互相通讯。 2. Xmpp协议内容:XMPP定义了客户端与服务器、服务器与服务器之间进行即时消息传递和在线状态呈现...
Pandion是一款专为用户提供简单、直观的即时通讯体验的软件,它基于开放标准的XMPP(Extensible Messaging and Presence Protocol)和Jabber协议。Pandion不仅提供基本的聊天功能,还支持群组聊天、文件传输等多样化...
Jabber 是最早实现 XMPP 协议的即时通讯系统之一,而 XMPP 实际上是 Jabber 协议的一个标准化版本。两者之间的关系可以这样理解:XMPP 是一种开放标准,而 Jabber 是该标准的一种具体实现。通过使用 XMPP 协议,...