在XMPP協議中,咱們使用presence來獲取用戶是否已經上線以及是否能夠通訊的狀態。html
爲了可以知道本身聯繫人的狀態以及讓聯繫人知道本身的狀態,用戶上線後須要訂閱聯繫人的狀態,聯繫人也一樣須要訂閱用戶的狀態。node
經過下面的消息訂閱聯繫人的狀態:編程
<presence from="alice@wonderland.lit" to="sister@realworld.lit" type="subscribe"/>
當聯繫人接收/拒絕訂閱時,會發送消息的消息體(sucribed/unsubscribe)迴應。緩存
一般客戶端是自動迴應這些消息的,當咱們訂閱了聯繫人的狀態以後,也會受到聯繫人的狀態變動信息。安全
還能夠經過嵌入<show/>(chat/away/xa/dnd)和<status/>元素表示更加豐富的信息。服務器
<presence> <show>away</show> <status>Having a spot of tea</status> </presence>
須要注意的是presence節是佔用帶寬最多的節,任何對該節內容的擴展都須要慎重。網絡
另外,presence還提供priority屬性用來標識資源的優先級(-127-128),負數優先級的資源將沒法接收消息,除非顯式指定,這個特性一般是由服務器實現的。session
另外,咱們能夠經過發送directed presence到其餘用戶,來避免訂閱對方信息,很是適合應用於網絡而上的簡短交流。dom
能夠經過發送<presence type=」unavailable」 />發送下線通知,服務器會完成消息保存,聯繫人通知等一系列操做。ide
presence也有其富文本形式,能夠包含更多信息,但不建議在presence中使用(資源和帶寬)。Publish-Subscribe[XEP-0060]和Personal Eventing Protocal[XEP-0163]提供了相似功能,但presence是針對整個花名冊廣播的。
服務器返回的花名冊中還能夠包含更加豐富的信息,包括用戶組以及訂閱狀況。
用戶對花名冊的修改也能夠經過發送IQ-set(rost-push)同步到服務器及其餘客戶端上(用戶可能有手機/pad等)。這種只推送變動的機制能夠簡化客戶端編程並節省流量。
獨立消息,將會立刻投遞或者緩存,是默認消息類型
用戶聊天,經過session創建,一般處理一系列消息
多人聊天,一般此類型會指定一個組件或者模塊處理多人聊天,該模塊會爲每一個參與者發送消息
全體通知,不會緩存,當即投遞
錯誤信息節,反饋錯誤信息
若是用戶不在線,則消息被緩存,用戶登陸後,消息推送給用戶,並攜帶消息原始產生時間,用於客戶端對消息進行排序。
能夠參考Delayed Delivery[XEP-0203]
chat session用於用戶頻繁交流的狀況,這相似於現實狀況中的聊天,其創建過程爲:雙方用戶在消息交互中知道了對方的Full JID,所以能夠直接通訊,響應的機制稱爲chat session。
相似於QQ的「正在輸入」功能,讓交互雙方瞭解即時狀態。
該功能擴展由XEP-0085定義。若是用戶不但願對方看到本身的狀態,能夠選擇不響應<active/>節。
已經定義好的狀態有:Starting,Active,Composing,Paused,Inactive,Gone
消息相似於:
<message from=you@yourdomain.tld/work to=daughter@yourdomain.tld type="chat"> <body>Hi honey!</body> <active xmlns="http://jabber.org/protocol/chatstates"/> </message>
能夠在message消息中加入XHTML用於富文本展現。
協議能夠在[XEP-0071]中找到。
<message from=you@yourdomain.tld/home to=friend@theirdomain.tld type="chat"> <body>I love this movie I saw last night, it's awesome!</body> <html xmlns="http://jabber.org/protocol/xhtml-im"> <body xmlns="http://www.w3.org/1999/xhtml"> <p> I <em>love</em>, this new movie I saw last night, it's <strong>awesome</strong>! </p> </body> </html> </message>
很容易注意到,消息中包含一個不包含格式的文本,以及XHTML格式的文本,是由於考慮到客戶端若是不支持HTML,也能夠正常展現。
HTML節中不能夠包含HEAD中的信息,也不能包含腳本(安全性考慮)。
也就是虛擬名片,用戶在聊天時能夠經過虛擬名片查看相關信息。
參考[XEP-0054]
虛擬名片服務經過發送IQ請求查看和更新,但須要注意的是,更新虛擬名片時須要發送完整的信息而不是隻有要更新的部分。
查詢請求:
<iq from=mouse@wonderland.lit/pool id="pw91nf84" to=alice@wonderland.lit type="get"> <vCard xmlns="vcard-temp"/> </iq>
返回的消息:
<iq from=alice@wonderland.lit id="pw91nf84" to=mouse@wonderland.lit/pool type="result"> <vCard xmlns="vcard-temp"> <N> <GIVEN>Alice</GIVEN> </N> <URL>http://wonderland.lit/~alice/</URL> <PHOTO> <EXTVAL>http://www.cs.cmu.edu/~rgs/alice03a.gif</EXTVAL> </PHOTO> </vCard> </iq>
更新名片:
<iq from=alice@wonderland.lit/pda id="w0s1nd97" to=alice@wonderland.lit type="set"> <vCard xmlns="vcard-temp"> <N> <GIVEN>Alice</GIVEN> </N> <URL>http://wonderland.lit/~alice/</URL> <PHOTO>
<EXTVAL>http://www.cs.cmu.edu/~rgs/alice03a.gif</EXTVAL> </PHOTO> <EMAIL> <USERID>alice@wonderland.lit</USERID> </EMAIL> </vCard> </iq>
相似於QQ可黑名單機制,能夠對某人隱身,不看某人的消息或屏蔽某個域的消息等等;固然也包括對名單的修改。
該功能可支持的粒度很是細,參考標準[XEP-0016],[XEP-0191]。
發送一條消息給多個接受者而不經過聊天室
控制消息過時,避免消息被本地存儲以及延時投遞等
客戶端層面確認消息是否已經送達
在服務器上存儲消息,而不是在客戶端機器上存儲
咱們須要知道系統中有哪些實體,以及該實體支持哪些服務,爲了完成這些操做,引入了實體發現和服務發現的概念。
XMPP 服務發現協議[XEP-0030]定義了兩個基本的發現方法。首先發現disco#items,disco#info。
<iq from=hatter@wonderland.lit/home id="xl391n47" to="wonderland.lit" type="get"> <query xmlns="http://jabber.org/protocol/disco#items"/> </iq>
<iq from="wonderland.lit" id="xl391n47" to=hatter@wonderland.lit/home type="result"> <query xmlns="http://jabber.org/protocol/disco#items"> <item jid="conference.wonderland.lit"/> <item jid="notify.wonderland.lit"/> </query> </iq>
<iq from=hatter@wonderland.lit/home id="gq02kb71" to="conference.wonderland.lit" type="get"> <query xmlns="http://jabber.org/protocol/disco#info"/> </iq>
<iq from="conference.wonderland.lit" id="gq02kb71" to=hatter@wonderland.lit/home type="result"> <query xmlns="http://jabber.org/protocol/disco#info"> <identity category="conference" type="text" name="Chatrooms"/> <feature var="http://jabber.org/protocol/muc"/> <feature var="jabber:iq:register"/> <feature var="vcard-temp"/> </query> </iq>
服務發現一樣適用iq-get的disco#items/disco#info這兩個查詢操做,只是將查詢是服務而非實體。
具體的查詢步驟較爲複雜。
這種場景應用於用戶的花名冊向用戶返回是否在線的信息,這種判斷是否在線的信息帶有Full JID,所以能夠經過disco#info/disco#item來查詢。
可是這種查詢可能返回某個Full JID攜帶的所有信息,致使數據量過大,所以引入了下面的方式。
是對上面方法的改進,經過將實體支持的特性HASH爲一組特徵嗎,客戶端接收該特徵碼後與本地存儲進行比較,若是已有該特徵碼,則能夠得到支持的特性列表;若是客戶端沒有緩衝該特徵碼,則從新發送disco#info消息獲取,並緩存。
採用此種方法能夠節省響應的資源。
而且經過presence節就能夠獲取客戶端支持的功能了。
相似於HTML的表單,有工做流的特徵,能夠實現用戶驗證碼輸入和確認等功能。
由[XEP-0004]定義。
3.1 消息在全部的參與者中共享
3.2 全部的參與者都有一個room roster
3.3 參與者都使用其nickname標識,而不是實際的JabberID
3.4 房間共享參與信息
3.5 參與者不只限於人,也能夠是服務等
5.1 用戶發送presence消息
5.2 聊天室向成員廣播該presence
5.3 聊天室向用戶發送成員的presence
5.4 聊天室向用戶發送一些歷史消息好讓用戶參與討論,消息數目可配置,且消息帶有時間戳
<delay xmlns="urn:xmpp:delay" stamp="2008-11-07T18:42:03Z"/>
5.5 以後的聊天消息再也不攜帶時間戳
5.6 聊天室之間的消息往來,消息類型爲groupchat
<presence from=dormouse@wonderland.lit/sleepspace to=teaparty@conference.wonderland.lit/Dormouse type="unavailable"/>
羣組中有多重角色,不一樣的角色擁有不一樣的權限,能夠將用戶臨時踢出,或加入黑名單等。
具體有:outcast,visitor,participant,member,moderator,admin,owner。
另外房間也有不一樣的類型,有指定名單的,有臨時的,有隱藏的,有固定的等。
用戶能夠設置其在聊天室內的暱稱,參考In-Band Registration[XEP-0077]。
多人聊天能夠進行配置,有很是多的可配置項,列出以下。
配置項 |
做用 |
allowinvites |
是否容許普通成員邀請 |
changesubject |
是否非管理員可以更改聊天室主題 |
enablelogging |
是否開啓記錄歸檔 |
getmemberlist |
是否可以獲取成員列表 |
lang |
語言 |
maxuser |
最大參與者數量 |
membersonly |
是否僅會員可加入(適用於member類型聊天室) |
persistentroom |
房間是否爲永久(全部成員退出也不會刪除) |
presencebroadcast |
是否廣播presence消息,對大room有用 |
publicroom |
該room是否可被發現 |
roomadmin |
設置room管理員 |
roomdesc |
設置room描述 |
roomname |
設置room名稱 |
roomowner |
設置room 全部者 |
whois |
控制是否匿名等 |
除了文字以外,MCU還能夠傳輸地理信息,文件和進行遠程調用等。
實際上就是消息系統中的推模式,主要分三個步驟完成:首先訂閱一個主題;其次發佈一個消息;最後消息被推送到訂閱客戶端。[XEP-0060]
訂閱者須要訂閱一個源,發佈者也將消息發佈到這個源。
流程:
若是成功則能夠接收消息了,若是失敗,則有多是要求更多的配置信息
主要分爲兩個部分。
發佈方發佈消息到源;服務器將源的消息經過message的形式投遞給訂閱方。
須要注意的是:發佈方只負責將消息推送至源,投遞的邏輯由訂閱方的服務器完成。
用戶能夠選擇是否在通知中攜帶payloads,如通知中包含頭像信息時,只須要metadata,無需具體的數據。
是否啓用payload能夠經過配置項deliver_payloads來實現。
是否保存items也是能夠配置的,能夠經過persist_items配置。
保存/不保存數據的node分別稱爲persistent nodes/transient node。
nodes及其服務能夠經過disco#info/disco#item來查詢
返回的結果能夠經過以上兩個命令進一步查詢,直到找到想要訂閱的node。
若是用戶想訂閱某個好友的動態,可使用用戶的JID做爲datanode,相應的簡化協議稱爲PEP[XEP-0163](Personal Eventing Protocal)。
用戶能夠應用PEP協議,在本身的Presence消息中包含本身的愛好信息,服務器收到該presence後,將會根據此愛好向用戶推送好友的動態。
包括User Tune,User Location,User Activity,User Mood,User Nickname,User Avatar等。