最新消息:备用域名:https://yeeach.me

Jabber协议分析之Subscriptions运行机制-Presence subscription

技术 admin 1996浏览 0评论

    手机客户端需要实现即时通信功能,在通信协议上采用开放的Jabber(XMPP)协议,整个XMPP协议最为核心也是最为复杂的部分是Subscription的运行机制,抓取了一下相关的通信协议报文,供开发时候参考。

  

1. 测试环境

1.1. 测试软件环境:

    Jabber服务器:Openfire 3.5.2

    Jabber客户端:Spark 2.5.8

抓包:Wireshark

1.2. 服务器环境:

    Jabber服务器:192.168.1.12,安装Openfire,域为home1

    Jabber用户客户端:192.168.1.10,安装Spark客户端,Jabber用户为chuanliang。

    Jabber联系人客户端:192.168.1.11,安装Spark客户端,Jabber用户为liangchuan

1.3. 测试场景:

测试1:

    Jabber用户chuanliang和Jabber联系人liangchuan被彼此的presence订阅,且允许把彼此加入自己的Roster

测试2

    Jabber联系人liangchuan接受Jabber用户chuanliang的订阅,但是不允许chuanliang加入自己的Roster

测试3

    Jabber联系人liangchuan不接受Jabber用户chuanliang的订阅,同时不允许chuanliang加入自己的Roster

以测试用例“测试1”说明一下测试过程:

1、 [email protected]在192.168.1.10客户端上新增联系人[email protected]

2、 [email protected]在192.168.1.11客户端上“准许[email protected]新增[email protected]到chuanlian的联系人名单中”,同时”Add user to liangchuan’s  roster”

clip_image002

3、 [email protected]在192.168.1.10客户端上“准许[email protected]新增[email protected]到chuanlian的联系人名单中”,同时”Add user to chuanliang’s  roster”

clip_image004

2. 测试1- contact accept subscription and allow add user to it’s roster

2.1. Jabber用户客户端发送一个type=’set’ 的Roster Update请求给Jabber服务器端

Ø 192.168.1.10->192.168.1.12

Jabber用户客户端发送一个<iq/>包给Jabber服务器端,其jabber:iq:roster名字空间中包含一个type=’set’,用于更新自己的roster

<iq id="7SJ55-63" type="set">

    <query xmlns="jabber:iq:roster">

        <item jid="[email protected]" name="liangchuan">

            <group>Friends</group>

        </item>

    </query>

</iq>

Ø 192.168.1.12->192.168.1.10

Jabber用户客户端从服务器接收到一个“roster push”,产生一个新的roster条目,其subscription状态置为“none”:

<iq type="set" id="308-51" to="[email protected]/spark">

    <query xmlns="jabber:iq:roster">

        <item jid="[email protected]" name="liangchuan" subscription="none">

            <group>Friends</group>

        </item>

    </query>

</iq>

Ø 192.168.1.12->192.168.1.10

Jabber用户客户端在成功的情况下,从服务器接收到一个<iq/>包,其type=’result’。

<iq type="result" id="7SJ55-63" to="[email protected]/spark"/>

2.2. Jabber用户客户端发送一个type=’subscribe’的<presence/>的包给联系人客户端

Jabber用户客户端发送一个type=’subscribe’的<presence/>的包给联系人(发送给到Jabber服务器)

Ø 192.168.1.10->192.168.1.12

<presence id="7SJ55-64" to="[email protected]" type="subscribe"/>

Ø 192.168.1.12->192.168.1.10

Jabber用户客户端接着从服务器收到包含联系人待定子状态的’none’订阅状态的“roster push”;这个待定子状态在其联系人名单中包含一个ask=’subscribe’属性:

<iq type="set" id="132-52" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="liangchuan" ask="subscribe" subscription="none">

<group>Friends</group>

</item>

</query>

</iq>

2.3. Jabber服务器发送一个type=’subscribe’的<presence/>的Roster push包给联系人客户端

Ø 192.168.1.12->192.168.1.11

Jabber服务器在接收到192.168.1.10发送的type=’subscribe’的<presence/>的包后,然后发送一个type=’subscribe’的<presence/>的包给联系人客户端

<presence id="7SJ55-64" to="[email protected]" type="subscribe" from="[email protected]"/>

Ø 192.168.1.11->192.168.1.12

Jabber联系人客户端发送一个<iq/>包给Jabber服务器,其jabber:iq:roster名字空间中包含一个type=’set’,用于更新自己的roster:

<iq id="8SAVC-26" type="set">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="chuanliang">

<group>Friends</group>

</item>

</query>

</iq>

Ø 192.168.1.12->192.168.1.11

Jabber联系人客户端从服务器接收到一个<iq/>包,其type=’result’

<iq type="result" id="8SAVC-26" to="[email protected]/spark"/>

2.4. Jabber联系人客户端发送一个type=’subscribe’的<presence/>的包给用户客户端

此部分请求发生在联系人客户端“准许[email protected]新增[email protected]到chuanlian的联系人名单中”时候同时选择了:“Add user to liangchuan’s  roster”选项。如果没有选择,则无此部分请求。

Ø 192.168.1.11->192.168.1.12

<presence id="8SAVC-27" to="[email protected]" type="subscribe"/>

Ø 192.168.1.12->192.168.1.10

服务器传递请求给Jabber用户端

<presence id="8SAVC-27" to="[email protected]" type="subscribe" from="[email protected]"/>

Ø 192.168.1.12->192.168.1.10

<iq type="set" id="867-55" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name
="liangchuan" subscription="to">

<group>Friends</group>

</item>

</query>

</iq>

2.5. Jabber联系人客户端接收订阅请求,发送一个type=’subscribed’的<presence/>的包给用户客户端

联系人下一步要做的就是决定是否接受订阅请求。我们假定联系人接受订阅请求

Ø 192.168.1.11->192.168.1.12

联系人的Jabber客户端发送一个type=’subscribed’的<presence/>的包给Jabber用户(通过服务器端)

<presence id="8SAVC-28" to="[email protected]" type="subscribed"/>

Ø 192.168.1.12->192.168.1.10

<presence id="8SAVC-28" to="[email protected]" type="subscribed" from="[email protected]"/>

<presence id="8SAVC-6" from="liangc[email protected]/spark" to="[email protected]/spark">

<status/>

<priority>1</priority>

</presence>

Ø 192.168.1.12->192.168.1.11

联系人的Jabber客户端从服务器接收一个“roster push”包含Jabber用户的条目,其中subscription状态置为“from”

<iq type="set" id="14-54" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="chuanliang" ask="subscribe" subscription="from">

<group>Friends</group>

</item>

</query>

</iq>

2.6. Jabber用户客户端接收订阅请求,发送一个type=’subscribed’的<presence/>的包给联系人客户端

Ø 192.168.1.10->192.168.1.12

<presence id="7SJ55-65" to="[email protected]" type="subscribed"/>

Ø 192.168.1.12->192.168.1.10

<iq type="set" id="382-56" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="liangchuan" subscription="both">

<group>Friends</group>

</item>

</query>

</iq>

Ø 192.168.1.12->192.168.1.11

<iq type="set" id="697-57" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="chuanliang" subscription="both">

<group>Friends</group>

</item>

</query>

</iq>

Ø 192.168.1.12->192.168.1.11

<presence id="7SJ55-65" to="[email protected]" type="subscribed" from="[email protected]"/>

<presence id="7SJ55-51" from="chuanl[email protected]/spark" to="[email protected]/spark">

<status/>

<priority>1</priority>

</presence>

3. 测试2- contact accept subscribption and not allow add user to it’s roster

3.1. Jabber用户客户端发送一个type=’set’ 的Roster Update请求给Jabber服务器端

Ø 192.168.1.10->192.168.1.12

Jabber用户客户端发送一个<iq/>包给Jabber服务器端,其jabber:iq:roster名字空间中包含一个type=’set’,用于更新自己的roster

<iq id="xHk99-51" type="set">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="liangchuan">

<group>Friends</group>

</item>

</query>

</iq>

Ø 192.168.1.12->192.168.1.10

Jabber用户客户端从服务器接收到一个“roster push”,产生一个新的roster条目,其subscription状态置为“none”:

<iq type="set" id="133-130" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="liangchuan" subscription="none">

<group>Friends</group>

</item>

</query>

</iq>

Ø 192.168.1.12->192.168.1.10

Jabber用户客户端在成功的情况下,从服务器接收到一个<iq/>包,其type=’result’。

<iq type="result" id="xHk99-51" to="[email protected]/spark"/>

3.2. Jabber用户客户端发送一个type=’subscribe’的<presence/>的包给联系人客户端

Jabber用户客户端发送一个type=’subscribe’的<presence/>的包给联系人(发送给到Jabber服务器)

Ø 192.168.1.10->192.168.1.12

<presence id="xHk99-52" to="liangc[email protected]" type="subscribe"></presence>

Ø 192.168.1.12->192.168.1.10

Jabber用户客户端接着从服务器收到包含联系人待定子状态的’none’订阅状态的“roster push”;这个待定子状态在其联系人名单中包含一个ask=’subscribe’属性:

<iq type="set" id="35-132" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" name="liangchuan" ask="subscribe" subscription="none">

<group>Friends</group>

</item>

</query>

</iq>

3.3. Jabber服务器发送一个type=’subscribe’的<presence/>的Roster push包给联系人客户端

Ø 192.168.1.12->192.168.1.11

Jabber服务器在接收到192.168.1.10发送的type=’subscribe’的<presence/>的包后,然后发送一个type=’subscribe’的<presence/>的包给联系人客户端

<presence id="xHk99-52" to="[email protected]" type="subscribe" from="[email protected]"/>

3.4. Jabber联系人客户端接收订阅请求,发送一个type=’subscribed’的<presence/>的包给用户客户端

联系人下一步要做的就是决定是否接受订阅请求。我们这里联系人接受订阅请求,但是取消”Add user to chuanliang’s  roster”操作。

Ø 192.168.1.11->192.168.1.12

联系人的Jabber客户端发送一个type=’subscribed’的<presence/>的包给Jabber用户(通过服务器端)

<presence id="8SAVC-90" to="chuanli[email protected]" type="subscribed"></presence>

Ø 192.168.1.12->192.168.1.10

<presence id="8SAVC-90" to="[email protected]" type="subscribed" from="[email protected]"/>

<presence id="8SAVC-30" from="liangc[email protected]/spark" to="[email protected]/spark">

<status/>

<priority>1</priority>

</presence>

Ø 192.168.1.12->192.168.1.11

联系人的Jabber客户端从服务器接收一个“roster push”包含Jabber用户的条目,其中subscription状态置为“from”

<iq type="set" id="585-135" to="[email protected]/spark">

<query xmlns="jabber:iq:roster">

<item jid="[email protected]" subscription="from"/>

</query>

</iq>

4. 测试3- contact not accept subscription and  not allow add user to it’s roster

4.1. Jabber用户客户端发送一个type=’set’ 的Roster Update请求给Jabber服务器端

转载请注明:出家如初,成佛有余 » Jabber协议分析之Subscriptions运行机制-Presence subscription

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址