什么是出席
在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-權威指南(圖書)