什么是出席
在XMPP中,通过一种叫做出席的技术,你可以知道你的联系人什么时候在线和可进行通讯。因为客户端通过一个灯泡图标会告诉你联络现在是否可用。用过QQ的同学一定知道QQ有好友在线,离线等状态。
授权需要: 握手订阅
出席是自发的,没有人强迫你和别人交换关于自己网络可用性的信息。但是,如果你决定要交换这些信息,你做出了一个信任他人的决定,这就使得某个人,不同于其他任何人,能够发现你的出席。你信任的人会自动被加入一个联络列表,这个列表就是任何即时消息和实时通信的花名册。
出席连接的过程是双向的,你允许一个联络者看到你的出席,那么你也可以看到他的出席,这个过程是通过一个叫做“握手”的订阅完成的。
握手订阅过程
为了获取某个人的出席信息,你给他发送一个订阅请求(通过subscribe类型)
<presence from="suke@skh.whu.edu.cn" to="beta@skh.whu.edu.cn" type="subscribe"/>
当指定的接受者接受到你的出席订阅请求时,他可以接受它(通过subscribed类型)或者拒绝它(通过unsubscribed类型)
<presence from="beta@skh.whu.edu.cn" to="suke@skh.whu.edu.cn" type="subscribe">
当一个人接受了对方发送的订阅请求之后,也需要返回一个订阅请求给对方
<presence from="beta@skh.whu.edu.cn" to="suke@skh.whu.edu.cn" type="subscribe"/>
一般来说,客户端会自动同意这个请求,而不是要求你同意对方的请求
<presence from="suke@skh.whu.edu.cn" to="beta@skh.whu.edu.cn" type="subscribe"/>
一旦你订阅了另一个人的出席信息,当他得到网络状态改变的时候,你会自动得到通知。通知信息的格式如下:
<presence from="beta@skh.whu.edu.cn" to=" suke@skh.whu.edu.cn">
<show>xa</show>
<status>down the rabbit hole!</status>
</presence>
出席是怎么传播的
出席信息如何在你和你的订阅者之间传播的
- 你和你的服务器商议xml流信息
- 你发送一个初始化的出席节到你的服务器
- 你的服务器检查你的名册,然后发送一个出席通知到订阅你的每一个人
<presence from="suke@skh.whu.edu.cn"
to="beta@skh.whu.edu.cn"/>
<presence from="suke@skh.whu.edu.cn"
to="gmz@skh.whu.edu.cn"/>
- 试想:现在每一个订阅了你的出席的人都知道你在线了,并且可以通讯,但是你怎么知道他们是否在线呢?
这里, 你的服务器再一次发挥作用,因为它发送一个出席调查给你订阅的每一个人:
<presence from="suke@skh.whu.edu.cn"
to="beta@skh.whu.edu.cn"
type="probe"/>
<presence from="suke@skh.whu.edu.cn"
to="gmz@skh.whu.edu.cn"
type="probe"/>
- 一旦你的联络者的服务器接受到了调查,他们根据记录检测许可,如果你被允许查看联络者的出席信息,你将至少会收到来自哪些在线的人的一次通知,有时不在线的也会给你一个通知,包括上一次出席通知的发送时间
<presence from="gmz@skh.whu.edu.cn"
to="suke@skh.whu.edu.cn"
type="unavailable">
<delay xmlns="urn:XMPP:delay"
stamp="2008-11-26T15:59:09Z"/>
</presence>
<presence from="lj@skh.whu.edu.cn"
to="suke@skh.whu.edu.cn"/>
<presence from="skh@skh.whu.edu.cn"
to="suke@skh.whu.edu.cn"/>
可用性状态
出席不只是简单的网络是否可用,有两种主要的出席元素可以表达丰富的信息show元素和status元素
show
show元素有四种预设值,它反映了一个用户对于通信的能力和兴趣
聊天
离开
长时间离开
忙碌
status
status元素允许用户指定自由的格式,易于阅读的文本来再更详细的层次上描述用户可用性。例如:一个用户可以给show赋值为away,status赋值为"having tea with white Rabbit"
<presence>
<show>away</show>
<status>Having a spot of tea</status>
</presence>
出席优先级
xmpp允许你在同一时间连接多个设备或者客户端到同一账号。这就引出了设备间通讯的可能性。(例如,你可以用办公室的电脑控制家里的机顶盒)。这通常通过JabberId的部分资源来完成,例如me@myserver.tld/TV,me@myserver.tld/office。每个连接的资源可以标识一个优先级,范围:-127~128.高优先级的资源更容易接受到发送给简化ID的消息。有负值的资源永远不会收到这样的消息。
<presence from="suke@skh.whu.edu.cn/office">
<priority>7</priority>
</presence>
<presence from="suke@skh.whu.edu.cn/TV">
<priority>-1</priority>
</presence>
定向出席
你可能希望和一个人临时通话,但不想把他加入到自己的联系人列表,这种情况下你可以对那个人发送定向出席。
举例:
当suke来到一个兔子洞里并遇到了一只白色的兔子的场景。因为兔子不在她的联络列表上,她将发送了一个消息,还有一个定向出席。
<message from="suke@skh.whu.edu.cn"
to="whiterabbit@skh.whu.edu.cn"
type="chat">
<body>If you please,sir--</body>
</message>
<presence from="suke@skh.whu.edu.cn"
to="whiterabbit@skh.whu.edu.cn"/>
白色兔子因为太过害怕无法回答,但是他的IM客户端至少发送了一个定向出席给suke。
<presence from="whiterabbit@skh.whu.edu.cn/mobile"
to="suke@skh.whu.edu.cn"
type="unavailable"/>
这种不需要长期订阅的临时出席共享是在网络之间进行临时交互的最好方法。
下线
当你断开网络连接,你可以告诉服务器你现在的状态,从而轻易下线
<presence type="unavailable">
下线的含义:
你的服务器向你的联络列表中的所有人广播你不可用的通知
你的服务器同样向所有你发送了定向出席的实体广播你的不可用状态的通知
如果你没有其他的在线资源,当你的联系人的服务器接收到一个不可用通知时,它们应该会停止向你发送出席通知。
如果你没有其他的在线资源,你的服务器将停止发送信息给你,将它们储存起来,下次你上线时,将这些信息传递给你。
丰富出席
利用用出席小节来宣传你正在听的音乐
<presence>
<status>Pink Floyd - Dogs</status>
</presence>
这种类型的信息一般被叫做丰富出席或者扩展出席,它可以包括范围非常广的瞬时数据:你现在的心情和活动,你正在听的音乐,你正在看的视频,你正在访问的聊天室或者网页,你正在玩的游戏,你现在的地理位置等等。
缺点:
- 将所有的无结构的文本串信息放入<status/>元素中并不是一种XML友好的做法。
- 在出席中发送所有的信息会导致出现多得多的出席节,而且这些出席节可能会比现有的更大(或者大得多)。考虑到出席服务已经使用了比消息传递多得多的带宽,使用更大和更多的出席节会严重影响网络的性能。
- 不是你的联络列表中的所有人都会对你正在听什么音乐这类的问题感兴趣,所以为什么要发送这类信息呢?
- 你可能会想做出限制,让知道你的网络可用性的人中的一小部分可以知道你的地理位置或者其他的敏感信息。
基于诸如此类的考虑,丰富出席一般不适用出席运输,而是使用一种特别的出版订阅方法。
出席和名单
出席信息通常显示为用户名单的一部分(出席状态)。
你的花名册是由客户端管理的,但是它存储在你的主服务器上,这允许你从任意地方连接并取回联络列表。客户端通常向服务器发出IQ-get请求完成这些任务
<iq from="suke@skh.whu.edu.cn"
id="jh2gs675"
to="skh.whu.edu.cn"
type="get">
<query xmlns="jabber:iq:roster"/>
</iq>
在名单请求过程中,服务器忽略from后面的地址,因为它总是将名单送到请求它的实体中。(你不能请求其他人的名单)
目的地址是用户的JID的简写。这意味着服务器根据用户的账户来处理请求。这相当于,发送者可以完全不包含任何目的地址,因为发送用户对用目的地址和没目的地址是同等对待的。
用户服务器随后从服务器数据库中国年读取用户名单,并将它返回到请求的资源。
<iq from="skh.whu.edu.cn"
id="jh2gs675"
to="suke@skh.whu.edu.cn"
type="result">
<query xmlns="jabber:iq:roster">
<item jid="lx@skh.whu.edu.cn"/>
<item jid="lbh@skh.whu.edu.cn"/>
<item jid="gmz@skh.whu.edu.cn"/>
<item jid="skh@skh.whu.edu.cn"/>
<item jid="wc@skh.whu.edu.cn"/>
</query>
</iq>
这是最简单的返回数据,服务器可能返回更复杂的数据,包括用户组,用户资料等。
当联络表中的某一个用户更新的资料,服务器会发送一个只包含该项目的IQ集成所有推送到您所连接的客户端。这就是IQ集,称为名册推送。
<iq from="skh.whu.edu.cn"
id="vzx274k7"
to="suke@skh.whu.edu.cn"
type="set">
<query xmlns="jabber:iq:roster">
<item jid="gmz@skh.whu.edu.cn">
<group>测试组</group>
</item>
</query>
</iq>
因为服务器总是推送一个变化到连接的客户名单,客户端只需等待和处理推送名册。
使用出席
以出席为基础的路由
访问控制
出席传输
参考资料:
xmpp系列笔记
xmpp-权威指南(图书)