JSON

使用 XMPP 构建一个基于 web 的通知工具(2)

字号+ 作者:H5之家 来源:H5之家 2016-07-11 17:00 我要评论( )

要促进消息传递,每个 XMPP 客户端用户必须拥有一个全局惟一标识符。基于历史原因,这些标识符称为 Jabber IDs,或称为 JIDs。鉴于这个协议的分布式特征,重要的是 JID 应包含联系用户所需的所有信息:不存在将用户

要促进消息传递,每个 XMPP 客户端用户必须拥有一个全局惟一标识符。基于历史原因,这些标识符称为 Jabber IDs,或称为 JIDs。鉴于这个协议的分布式特征,重要的是 JID 应包含联系用户所需的所有信息:不存在将用户链接到他们连接到的服务器的中央知识库。JID 的结构类似于电子邮件地址(但不要求 JID 同时也是有效的电子邮件收件人)。

客户端和服务器节点,我将它们统称为 XMPP 实体,都拥有 JIDs。SomeCorp 公司的员工 John Doe 可能拥有 JID John.Doe@somecorp.com。这里,somecorp.com 是 SomeCorp 公司的 XMPP 服务器的地址,John.Doe 是 John Doe 的用户名。

JIDs 还拥有连接到它们的资源。这允许在一个 XMPP 实体标识符之外进一步处理细粒度;例如,尽管上面的示例总体上能够表示 John Doe,但 John.Doe@somecorp.com/Work 可以用于将数据发送到与他的工作相关的工具。

这些资源可以采用任意用户定义的名称,一个 XMPP 实体可以拥有任意数量的资源。除了可以是上下文依赖的外,它们还可以绑定到设备、工具或工作站。对于您的 Pingstream 示例,web 站点的每个访问者都将作为同一个用户登录 XMPP 服务器,但他们拥有不同的资源。

通信类别

使用 XMPP 的实时消息传递系统包含三大通信类别:

  • 消息传递,其中数据在有关各方之间传输;
  • 联机状态,它允许用户广播其在线状态和可用性;
  • 信息/查询请求,它允许 XMPP 实体发起请求并从另一个实体接收响应。
  • 这些类别是互补的。例如,如果用户或实体离线(尽管在许多用例中,理想的状态是服务器在用户返回之前一直持有用户的消息),则没有将数据发送给用户或发起一个实体的信息/查询请求的点。这些消息中的每一条都将通过一个完整的 XML 节 传递 — XML 节是以 XML 表达的独立信息项。

    这三种类型的 XMPP 节都拥有以下公共属性:

    基于 XMPP 的数据传输发生在一些 XML 流上,默认在端口 5222 上操作。这些 XML 流实际上是两个完整的 XML 文档,每个文档对应一个通信方向。一旦会话建立,stream 元素将打开。这个元素将封装整个通信文档。然后,一些节被注入这个文档的第二层。最后,一旦通信结束,stream 元素将关闭,形成一个完整的文档。

    例如, 展示了一个 stream 元素,它建立了从客户端到服务器的通信。

    清单 1. 建立从客户端到服务器的通信的 stream 标记

    <stream:stream from="[server]" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">

    消息

    一旦通信建立,客户端就能使用 message 元素将消息发送到另一个用户,message 元素包含以下任意子元素:

    但是,消息也可以非常简单,如 所示:

    清单 2. 样例消息

    <message from="sendinguser@somedomain" to="recipient@somedomain" xml:lang='en'> <body> Body of message </body> </message>

    对于提供实时 web 界面而言,消息节是最有用的节。“发布-订阅” 模型 — 在实时 web 应用程序中使用消息来传输数据的一种替代方法 — 将稍后介绍。

    信息/查询

    信息/查询节拥有广泛的功能。一个例子就是 “发布-订阅” 模型,在该模型中,发布者通知服务器某个特定资源进行了更新,服务器则通知已选择订阅这些通知并拥有适当授权的所有 XMPP 用户。

    来自发布者的一系列项目被编码为一些节,格式为基于 XML 的 Atom 发布格式。每个项目都包含在一个 item 元素内,然后合并到一个 pubsub 元素中,最后成为一个信息/查询节。在 (选自 XMPP 发布-订阅规范)中,Shakespeare's Hamlet(JID 为 hamlet@denmark.lit/blogbot)用他著名的独白发布一个更新到 pubsub.shakespeare.lit pubsub 更新节点:

    清单 3. 对 pubsub.shakespeare.lit pubsub 更新节点的更新

    <iq type="set" from="hamlet@denmark.lit/blogbot" to="pubsub.shakespeare.lit"> <pubsub xmlns="http://jabber.org/protocol/pubsub"> <publish node="princely_musings"> <item> <entry xmlns="http://www.w3.org/2005/Atom"> <title>Soliloquy</title> <summary> To be, or not to be: that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles, And by opposing end them? </summary> <link type="text/html" href="http://denmark.lit/2003/12/13/atom03"/> <id>tag:denmark.lit,2003:entry-32397</id> <published>2003-12-13T18:30:02Z</published> <updated>2003-12-13T18:30:02Z</updated> </entry> </item> </publish> </pubsub> </iq>

    信息/查询节也用于请求一个特定 XMPP 实体的有关信息。例如,在 中的节中,boreduser@somewhere 正在查找 friendlyuser@somewhereelse 拥有的公共项目。

    清单 4. 用户查找由 friendlyuser@somewhereelse 拥有的公共项目

    <iq type="get" from="boreduser@somewhere" to="friendlyuser@somewhereelse"> <query xmlns="http://jabber.org/protocol/disco#items"/> </iq>

    反过来,friendlyuser@somewhereelse 使用一列可被订阅到使用 “发布-订阅” 的项目进行响应,如 所示:

    清单 5. 使用一列项目响应

    <iq type="result" from="friendlyuser@somewhereelse" to="boreduser@somewhere"> <query xmlns="http://jabber.org/protocol/disco#items"> <item jid="stuff.to.do"/> <item jid="stuff.to.not.do"/> </query> </iq>

    在 中的信息/查询节中的每个返回项目都拥有一个可以订阅到的 JID。信息/查询还允许超出本教程范围的广泛的服务器信息请求。它们中的许多在针对多服务器环境的 web 应用程序上下文中有用,或者作为复杂的分散型协作框架的基础。

    联机状态

    联机状态信息包含在一个联机状态(presence)节中。如果 type 属性省略,那么 XMPP 客户端应用程序假定用户在线且可用。否则,type 可设置为 unavailable,或者特定于 pubsub 的值:subscribe、subscribed、unsubscribe 和 unsubscribed。它也可以是针对另一个用户的联机状态信息的一个错误或探针。

    一个联机状态节可以包含以下子元素:

    例如, 中的 boreduser@somewhere 可以用这个节来表明聊天意愿:

    清单 6. 样例联机状态通知

    <presence xml:lang="en"> <show>chat</show> <status>Bored out of my mind</status> <priority>1</priority> </presence>

    注意 from 属性此处省略。

    另一个用户 friendlyuser@somewhereelse 可以通过发送 中的节来探测 boreduser@somewhere 的状态:

    清单 7. 探测用户状态

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    网友点评