由于XMPP协议并没有很好的支持group,也就是说,client没有办法从server得到空的group list。为了解决这个问题,用户在client创建一个group,我们会将group list存到server的storage:groups中。group存放的格式如下:
<storage xmlns='http://jabber.com/jabber/storage:groups'> <group>Team</group> <group>Test Users</group> <group>US</group> <group>HF</group> <group>HZ</group> <group>SZ</group> </storage>
client每次login server时,首先会从storage:groups拿到一个group list,然后再去拿buddy list,得到buddy list以后,再将从storage:groups拿到的group list和buddy list中含有的group list做一个合并,得到一个完整的group list。
参考RFC 3921 chapter 7 关于roster的管理部分。
<iq to='[email protected]/balcony' type='result' id='roster_1'> <query xmlns='jabber:iq:roster'> <item jid='[email protected]' name='Romeo' subscription='both'> <group>Friends</group> </item> <item jid='[email protected]' name='Mercutio' subscription='from'> <group>Friends</group> </item> <item jid='[email protected]' name='Benvolio' subscription='both'> <group>Friends</group> </item> </query> </iq>
这里介绍几个概念,每个item表示一个contact(XMPP协议称为roster), name attribute表示这个contact的friendly name, subscription表示用户和contact之间的一个关系, RFC 3921 chapter 8详细介绍了subscription的内容。item/group说明了这个contact归属于哪一个/几个group中,如果这个用户属于多个group,在item下就会有多个group tag。
The state of the presence subscription in relation to a roster item is captured in the 'subscription' attribute of the <item/> element. Allowable values for this attribute are:
"none" -- the user does not have a subscription to the contact's presence information, and the contact does not have a subscription to the user's presence information
"to" -- the user has a subscription to the contact's presence information, but the contact does not have a subscription to the user's presence information
"from" -- the contact has a subscription to the user's presence information, but the user does not have a subscription to the contact's presence information
"both" -- both the user and the contact have subscriptions to each other's presence information
上面的定义来自RFC 3921 chapter 8,这里简单解释一下上面几个值得含义:
除了上面定义的subscription之外,还有一个相关的状态:subscription request; out subscription request可以在contact的item中体现出来,ask='subscribe'表示用户给这个contact发送了一个subscription request; in subscription request只能在用户收到的presence中体现出来(type为subscribe)。 将subscription request和上述定义的subscription value组合起来,就会得到一个完整的subscription的状态表。
下面的enum来之.h文件的定义
//I am A, the buddy is B typedef enum tagConSubscriptionType { ConSubscription_None = 0, ConSubscription_NoneOut, //A add B, B has no response, SO: B is in outstanding invitation group ConSubscription_NoneIn, //B add A, A has no response, SO: A will see request dialog ConSubscription_NoneOutIn,//A add B and B add A, neither response, SO: A will see request dialog, B is in outstd group ConSubscription_To, //A can see B's presence, B cannot see A, SO: B is in normal group ConSubscription_ToIn, //A can see B's presence, B add A, A no response, SO: A will see request dialog ConSubscription_From, //B can see A's presence, SO: B is in observer group ConSubscription_FromOut, //B can see A's presence, A add B, B no response, SO: B is in observer group and outstd group ConSubscription_Both, //A and B can see each other's presence, SO: B is in normal group }ConSubscriptionType;