一个XMPP的账号由三部分组成: 用户名(user/node),域名(domain)和资源(resource) 。例如 alice@xmpp.irusher.com/mobile ,user部分(或node)是alice,domain是xmpp.irusher.com,resource部分是mobile。user和domain组合也叫Bare JID,例如:alice@xmpp.i8i8i8.com ,Bare JID常用标识一个用户。包含了user,domain和resource的ID也叫Full JID,在Full JID中,resource一般用来区分一个用户的多个会话,可以由服务端或客户端指定。下面介绍一下resource的绑定过程。

资源绑定

客户端通过服务端的验证之后,应该给XMPP流绑定一个特殊的资源以使服务端能够正确的定位到客户端。客户端Bare JID后必须附带resource,与服务端交互时使用Full JID,这样就确保服务端和客户端传输XML段时服务端能够正确的找到对应的客户端。

当一个客户端通过一个资源绑定到XML流上后,它就被称之为"已连接的资源"。服务器应该允许同时处理多个”已连接的资源“,每个”已连接的资源“由不同的XML流合不同的resource来区分。

资源绑定用到的XML命名空间为 "urn:ietf:params:xml:ns:xmpp-bind" .

绑定过程

1. 验证通过

服务端在SASL协议成功,发送了响应的stream头之后,必需紧接着发送一个由'urn:ietf:params:xml:ns:xmpp-bind'标识的<bind/>元素。

  1. S:<stream:stream
  2. from='im.example.com'
  3. id='gPybzaOzBmaADgxKXu9UClbprp0='
  4. to='juliet@im.example.com'
  5. version='1.0'
  6. xml:lang='en'
  7. xmlns='jabber:client'
  8. xmlns:stream='http://etherx.jabber.org/streams'>
  9. S:<stream:features>
  10. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
  11. </stream:features>

2. 生成resource标识

一个资源标识至少在同一个Bare JID的所有resource标识中是唯一的,这一点需要由服务端来负责。

2.1 服务端生成resource标志

客户端通过发送一个包含空的<bind/>元素,类型为的setIQ来请求服务端生成resource标志。

  1. C:<iq id='tn281v37' type='set'>
  2. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
  3. </iq>

服务端生成后发送响应给客户端:

  1. S:<iq id='tn281v37' type='result'>
  2. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  3. <jid>
  4. juliet@im.example.com/4db06f06-1ea4-11dc-aca3-000bcd821bfb
  5. </jid>
  6. </bind>
  7. </iq>

失败情况:

  1. 一个Bare JID下已经达到了同时在线的上限;
  2. 客户端不被允许绑定资源

2.2 客户端设置resource标志

客户端也可以自己设置resource。

客户端通过发送一个包含<bind/>元素,类型为的setIQ来请求服务端生成resource标志。<bind/>元素包含一个子元素<resource/><resource/>元素包含长度非零的字符串。

  1. C:<iq id='wy2xa82b4' type='set'>
  2. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  3. <resource>balcony</resource>
  4. </bind>
  5. </iq>

服务端应该接受客户端提交的resource标志。服务端通过IQ返回一个<bind/>元素,其中包含了一个<jid>元素,<jid>元素中包含一个Full JID,其中的resource是客户端提交的resource标志。

  1. S:<iq id='wy2xa82b4' type='result'>
  2. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  3. <jid>juliet@im.example.com/balcony</jid>
  4. </bind>
  5. </iq>

服务端有可能会拒绝客户端提供的resource标志,而使用服务端生成的resource标志。

失败情况:

  1. 提交的标志包含非法字符,地址格式可以在这里查到: Address Format
  2. 提交的标志已经被占用

2.2.1 resource标志冲突

当客户端提供的resource标志冲突时,服务端应该遵循以下三个策略之一:

  1. 重新生成新连接提交的resource标志,使新连接能够继续;
  2. 拒绝新的连接,并维持现有的连接;
  3. 断开现有的连接,并尝试绑定新的连接;

如果是第一种情况,服务端返回重新生成的resource标志:

  1. S:<iq id='wy2xa82b4' type='result'>
  2. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  3. <jid>
  4. juliet@im.example.com/balcony 4db06f06-1ea4-11dc-aca3-000bcd821bfb
  5. </jid>
  6. </bind>
  7. </iq>

如果是第二种情况,服务端向新连接返回一个<conflict/>流错误:

  1. S:<iq id='wy2xa82b4' type='error'>
  2. <error type='modify'>
  3. <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  4. </error>
  5. </iq>

如果是第三种情况,服务端向已连接的客户端发送<conflict/>流错误,关闭已连接的客户端的流,然后向新的连接发送绑定的结果:

  1. S:<iq id='wy2xa82b4' type='result'>
  2. <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
  3. <jid>
  4. juliet@im.example.com/balcony
  5. </jid>
  6. </bind>
  7. </iq>

应用:强制下线

  类似QQ,不同设备上最多只能有一个账户在线,例如一个账号不能在两个iPhone上同时在线,在第二台上登录,就要把第一台踢下线,但是,又允许桌面或web上登录相同的账号。像这样的需求,可以通过resource标志来实现。

假定策略如下:一个账号最多只能在相同系统的设备上有一处登录,例如,用户在一台iPhone上登录,如果又在另外一台设备上登录,那就把第一台踢下线,但是可以允许有一个Android设备登录相同的账号。

实现: 在iOS版本中,登录时,客户端提交自定义的resource标志: iOS,同样,Android版本中,提交自定义的resource标志: Android。这样就可以限制相同系统只能有一处登录了。

假如要求一个账号只能在一个移动设备上登录,实现的时候,则需要iOS和Android使用相同的resource标志,例如: Mobile.

需要特别说明的是,当旧的连接被踢下线后,服务端向客户端发送<conflict/>流错误,并关闭流。客户端需要正确的处理这种情况下的应用逻辑。

XMPP资源绑定(Resource Binding)的更多相关文章

  1. XMPP资源绑定(Resource Binding)与单台设备登录控制

    原文:http://blog.csdn.net/brasbug/article/details/26353511 一个XMPP的账号由三部分组成: 用户名(user/node),域名(domain)和 ...

  2. DNS资源纪录(Resource Record)介绍

          http://dns-learning.twnic.net.tw/bind/intro6.html 类型 SOA NS A AAAA PTR CNAME MX -------------- ...

  3. 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合

    [源码下载] 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合 作 ...

  4. 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合

    背水一战 Windows 10 之 绑定 通过 Binding 绑定对象 通过 x:Bind 绑定对象 通过 Binding 绑定集合 通过 x:Bind 绑定集合 示例1.演示如何通过 Bindin ...

  5. java之多态(Polymorphic)、动态绑定(Dynamic Binding)、迟绑定(Late Binding)

    今天,我们来说说java面向对象最核心的东西,多态.通过多态可以使我们的程序可复用性达到极致,这就是我们为什么要学多态的原因. “多态”(Polymorphic)也叫“动态绑定”(Dynamic Bi ...

  6. WPF 之 资源(Resource)

    1.什么叫WPF的资源(Resource)? 资源是保存在可执行文件中的一种不可执行数据.在WPF的资源中,几乎可以包含图像.字符串等所有的任意CLR对象,只要对象有一个默认的构造函数和独立的属性. ...

  7. WCF 绑定(Binding)

    绑定包含多个绑定元素 ,它 们描述了所有绑定要求 .可以创建自定义绑定 ,也可以使用下表中的其中一个预定义绑定 : 不同的绑定支持不同的功能.以Ws开头的绑定独立于平台 ,支持 Web服务规范. 以 ...

  8. 嵌入的资源 和 Resource

    我们将资源文件添加至.net C#工程时,文件的生成操作有多种可选方式.通常用的多的是两种:[嵌入的资源]和[Resource],如果从需要从代码中使用这些资源文件,不同生成操作则对应不同的引用方式: ...

  9. spring mvc: 多解析器映射(资源绑定视图解析器 + 内部资源[普通模式/]视图解析器)

    spring mvc: 多解析器映射(资源绑定视图解析器 + 内部资源[普通模式/]视图解析器) 资源绑定视图解析器 + 内部资源(普通模式)视图解析器 并存方式 内部资源视图解析器: http:// ...

随机推荐

  1. GDB 命令详细解释

    Linux中包含有一个很有用的调试工具--gdb(GNU Debuger),它可以用来调试C和C++程序,功能不亚于Windows下的许多图形界面的调试工具. 和所有常用的调试工具一样,gdb提供了以 ...

  2. 转:ospf学习-----SPF最短路径算法

    ospf学习-----SPF最短路径算法 常见的路由协议比如RIP.IGRP.BGP是距离矢量协议,OSPF和ISIS是数据链路状态协议.矢量协议路由器只知道本身和与自身相连的接口路由信息,矢量图只是 ...

  3. go语言学习之路六:接口详解

    Go语言没有类和继承的概念,但是接口的存在使得它可以实现很多面向对象的特性.接口定义了一些方法,但是这些方法不包含实现的代码.也就是说这些代码没有被实现(抽象的方法).同时接口里面也不包含变量. 看一 ...

  4. WebStorm添加多个项目到当前工程目录

    File-> Settings -> Directories -> Add Content Root,选择你要加入的Project 点击OK -> Apply -> OK ...

  5. CBIntrospector俗称:内部检查工具

    Download View Introspector   (CBIntrospector)内部检查工具是IOS和IOS模拟器的小工具集,帮助在调试的UIKit类的用户界面,它尤其有用于动态UI布局创建 ...

  6. DEDECMS后台模板修改

    一.后台登录页 dede/templets/login.htm去掉底部的代码(类名为login-power.dede-iframe这两个div都要去掉)其中“login.php?dopost=show ...

  7. ylb:sql语句重命名表名和列名

    ylbtech-SQL Server:SQL Server-sql语句重命名表名和列名 sql语句重命名表名和列名 ylb:sql语句重命名表名和列名 返回顶部 一.更改数据库名    sp_rena ...

  8. 【转】如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等   你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作——一些无法并 ...

  9. 修改Centos默认源

    原文:http://mirrors.aliyun.com/help/centos?spm=5176.bbsr150321.0.0.d6ykiD 1.备份 mv /etc/yum.repos.d/Cen ...

  10. python 制作wordcloud词云

    pip install wordcloud 需要用到numpy  pillow matplotlib 安装完成以后 wordcloud_cli --text in.txt --imagefile ou ...