本文主要描述了rfc6121中关于联系人管理的部分,阅读本文之前需要对xmpp协议有基本的了解,看协议是比较麻烦的一件事情,一个是因为全英文,二是协议里的内容
很多人都会觉得晦涩难懂,那么我以我的角度把协议翻译了一下,希望能更容易理解。
1. 属性解释
1.1 ver 属性
ver属性代表了联系人信息的版本,值需要有服务器来生成,具体怎么生成由服务器来决定,例如可以用递增数字。
1.2item节点
在query节点下面的item节点具体表示了联系人的信息,
1.2.1Approved 属性
server需要这个属性来向client标识这个用户可以是预批准的(pre-approval),什么是预批准,简单讲可以理解为正常情况下a用户想加b用户为好友,需要b用户的批准,如果b用户设置了预批准,则b用户不需要手动批准,服务器帮其处理
1.2.2 ask属性
ask属性代表这个用户向这个联系人发送了订阅(presence)的消息,但对方还没回复
1.2.3 jid属性
jid属性是联系人的唯一标识
1.2.4 name属性
给联系人设置的昵称
1.2.5 Subscription 属性
标识用户和联系人的订阅关系
-
- "none" -- 这个用户没有对这个联系人出席信息的订阅, 这个联系人也没有订阅用户的出席信息
-
- "to" -- 这个用户订阅了这个联系人的出席信息, 但是这个联系人没有订阅用户的出席信息
-
- "from" -- 这个联系人订阅了用户的出席信息, 但是这个用户没有订阅这个联系人的出席信息
-
- "both" -- 用户和联系人互相订阅了对方的出席信息
1.3 group子节点
- 代表了用户属于哪个组,可以有多个
2.请求类型
请求类型大致分为4类:
2.1 Roster Get (请求server返回联系人信息,由client发出)
此为一个client向server请求返回用户的联系人列表C: <iq from='juliet@example.com/balcony'
id='bv1bs71f'
type='get'>
<query xmlns='jabber:iq:roster'/>
</iq>
2.2 Roster Result
server收到Roster Get 的请求后会响应一个 response ,Roster result 就是响应的result,S: <iq id='bv1bs71f'
to='juliet@example.com/chamber'
type='result'>
<query xmlns='jabber:iq:roster' ver='ver7'>
<item jid='nurse@example.com'/>
<item jid='romeo@example.net'/>
</query>
</iq>query节点下的item节点代表了返回的用户好友列表。多少个item就代表有多少个联系人,如果roster存在但没有联系人,则不返回item子节点。
2.3 Roster set
这是client发给server的一个请求要修改联系人的信息(包括新增,修改,删除),这里有些规定1)query这个节点下面的item子节点必须要有一个且只能有一个
2)item节点如果包含了subscription属性,如果对应的值不是remove,则其他的值server都忽略不处理,只有为remove时才处理,代表删除
S: <iq id='bv1bs71f'
to='juliet@example.com/chamber'
type='result'>
<query xmlns='jabber:iq:roster' ver='ver7'>
<item jid='nurse@example.com'/>
<item jid='romeo@example.net'/>
</query>
</iq>要注意验证发出set的发送方是否有权限
2.4.Roster push
是server发给client的有关新建,更新或者删除联系人的通知,规定1)query这个节点下面的item子节点必须要有一个且只能有一个
2)这个节必须没有from属性,或者from属性里的值和用户的裸id一致,client才处理这个节,否则 client需要忽略这个节
S: <iq id='a78b4q6ha463'
to='juliet@example.com/chamber'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'/>
</query>
</iq>可以看到和 Roster set的区别就是 from ,to属性,以及一个是从client发到server的一个是从server发到client的
client接到请求后可以返回个信息 result或者error(当前很多实现没这么做)
3.功能
3.1 在登录时获取联系人列表client发送请求:
C: <iq from='juliet@example.com/balcony'
id='hu2bac18'
type='get'>
<query xmlns='jabber:iq:roster'/>
</iq>server响应:
S: <iq id='hu2bac18'
to='juliet@example.com/balcony'
type='result'>
<query xmlns='jabber:iq:roster' ver='ver11'>
<item jid='romeo@example.net'
name='Romeo'
subscription='both'>
<group>Friends</group>
</item>
<item jid='mercutio@example.com'
name='Mercutio'
subscription='from'/>
<item jid='benvolio@example.net'
name='Benvolio'
subscription='both'/>
</query>
</iq>返回了用户所有联系人
3.2 添加联系人
client发出请求 ,item中是要加的好友:
C: <iq from='juliet@example.com/balcony'
id='ph1xaz53'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
name='Nurse'>
<group>Servants</group>
</item>
</query>
</iq>成功:
server如果接到了请求,并成功处理了请求则应该给发送请求的client一个返回。
S: <iq id='ph1xaz53'
to='juliet@example.com/balcony'
type='result'/>同时server应该产生个roster push到所有连接的客户端,作出通知S: <iq to='juliet@example.com/balcony'
id='a78b4q6ha463'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver13'>
<item jid='nurse@example.com'
name='Nurse'
subscription='none'>
<group>Servants</group>
</item>
</query>
</iq>
S: <iq to='juliet@example.com/chamber'
id='x81g3bdy4n19'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver13'>
<item jid='nurse@example.com'
name='Nurse'
subscription='none'>
<group>Servants</group>
</item>
</query>
</iq> 失败: 1)如果server遇到内部错误 会产生<internal-server-error/>
2)如果发起请求的client未被授权,应该返回<forbidden/>
3)如果<query/>有1个以上的item子节点,或者item有多个group子节点,并且是冲突的,那么将返回
<bad-request/>
4)如果name属性和group节点的内容长度超过服务器的限制,或者group节点内容为空,则返回<not-acceptable/>
例如:client未被授权的情况
C: <iq from='juliet@example.com/balcony'
id='ix7s53v2'
to='romeo@example.net'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'/>
</query>
</iq>
S: <iq id='ix7s53v2'
to='juliet@example.com/balcony'
type='error'>
<error type='auth'>
<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
3.3更新联系人信息
更新联系人信息和增加联系人一样都是发送的Roster set 请求,因为用户jid是唯一的,所以服务器来判断是增加还是更新比如以下下几种情况用户会更新联系人信息
1)给联系人加入分组,或修改其分组
2)给联系人增加或修改昵称等
成功
与增加联系人一样
失败
与增加联系人一样3.4删除联系人信息
当用户要删除联系人时,发送请求C: <iq from='juliet@example.com/balcony'
id='hm4hs97y'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
subscription='remove'/>
</query>
</iq>同样是一个Roster set 请求,但是 item节点下的 subscription属性是 remove
成功 :
除了要做和增加联系人一样的成功处理以外,还需要做出席(presence)相关的处理
1)如果用户订阅了联系人的出席信息,那么server 需要发出一个 type是"unsubscribe"的 presence 节给联系人
2)如果联系人订阅了用户的出席信息 ,那么server 需要发出一个 type是"unsubscribed"的 presence 节给联系人
3) 如果互相订阅了,那么server 要做1)2)
S: <presence from='juliet@example.com'
id='lm3ba81g'
to='nurse@example.com'
type='unsubscribe'/>
S: <presence from='juliet@example.com'
id='xb2c1v4k'
to='nurse@example.com'
type='unsubscribed'/>
失败:
如果server上没有这个联系人,则返回C: <iq from='juliet@example.com/balcony'
id='uj4b1ca8'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='[ ... non-existent-jid ... ]'
subscription='remove'/>
</query>
</iq>
S: <iq id='uj4b1ca8'
to='juliet@example.com/balcony'
type='error'>
<error type='modify'>
<item-not-found
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
理解XMPP协议中的联系人管理

本文深入解析了RFC6121中关于联系人管理的协议细节,旨在简化理解过程,通过属性解释和请求类型说明,清晰阐述了如何在XMPP协议下管理联系人信息,包括获取联系人列表、添加、更新、删除联系人及其相关信息的过程。
4408

被折叠的 条评论
为什么被折叠?



