Presence(http://www.cnblogs.com/jiyuqi/tag/xmpp/)node
在XMPP協議中,咱們使用presence來獲取用戶是否已經上線以及是否能夠通訊的狀態。
編程
爲了可以知道本身聯繫人的狀態以及讓聯繫人知道本身的狀態,用戶上線後須要訂閱聯繫人的狀態,聯繫人也一樣須要訂閱用戶的狀態。
緩存
經過下面的消息訂閱聯繫人的狀態:
服務器
當聯繫人接收/拒絕訂閱時,會發送消息的消息體(sucribed/unsubscribe)迴應。
網絡
一般客戶端是自動迴應這些消息的,當咱們訂閱了聯繫人的狀態以後,也會受到聯繫人的狀態變動信息。
session
還能夠經過嵌入(chat/away/xa/dnd)和元素表示更加豐富的信息。
dom
須要注意的是presence節是佔用帶寬最多的節,任何對該節內容的擴展都須要慎重。另外,presence還提供priority屬性用來標識資源的優先級(-127-128),負數優先級的資源將沒法接收消息,除非顯式指定,這個特性一般是由服務器實現的。
spa
另外,咱們能夠經過發送directed presence到其餘用戶,來避免訂閱對方信息,很是適合應用於網絡而上的簡短交流。
設計
能夠經過發送發送下線通知,服務器會完成消息保存,聯繫人通知等一系列操做。
orm
presence也有其富文本形式,能夠包含更多信息,但不建議在presence中使用(資源和帶寬)。Publish-Subscribe[XEP-0060]和Personal Eventing Protocal[XEP-0163]提供了相似功能,但presence是針對整個花名冊廣播的。
服務器返回的花名冊中還能夠包含更加豐富的信息,包括用戶組以及訂閱狀況。
用戶對花名冊的修改也能夠經過發送IQ-set(rost-push)同步到服務器及其餘客戶端上(用戶可能有手機/pad等)。這種只推送變動的機制能夠簡化客戶端編程並節省流量。
Instant Messaging
消息發送流程
user1向user2發送消息,user1位於domain1,user2位於domain2
user1的client1向server1發送消息節,server1設置from屬性
server1投遞消息給server2(直接通訊)
server2收到消息並檢查user2是否在線並投遞
normal
message消息類型
獨立消息,將會立刻投遞或者緩存,是默認消息類型
chat
用戶聊天,經過session 創建,一般處理一系列消息
groupchat
多人聊天,一般此類型會指定一個組件或者模塊處理多人聊天,該模塊會爲每一個參與者發送消息
headline
全體通知,不會緩存,當即投遞
error
錯誤的信息節,反饋錯誤信息
延時投遞
若是用戶不在線,則消息被緩存,用戶登陸後,消息推送給用戶,而且攜帶消息原始產生時間,用於客戶端對消息進行排序。
Chat session
chat session用於用戶頻繁交流的狀況,這相似於現實狀況中的聊天,其創建過程爲:雙方用戶在消息交互中知道了對方的Full JID,所以能夠直接通訊,響應的機制稱爲chat session。
狀態通知相似於QQ的「正在輸入」功能,讓交互雙方瞭解即時狀態。該功能擴展由XEP-0085定義。若是用戶不但願對方看到本身的狀態,能夠選擇不響應節。已經定義好的狀態有:Starting,Active,Composing,Paused,Inactive,Gone
格式化消息
能夠在message消息中加入XHTML用於富文本展現。
協議能夠在[XEP-0071]中找到。
vCards
也就是虛擬名片,用戶在聊天時能夠經過虛擬名片查看相關信息。
阻塞和過濾通訊
相似於QQ可黑名單機制,能夠對某人隱身,不看某人的消息或屏蔽某個域的消息等等;固然也包括對名單的修改。
更多消息擴展
Extended Stanza Addressing[XEP-0033]
發送一條消息給多個接受者而不經過聊天室
Advanced Message Processing[XEP-0079]
控制消息過時,避免消息被本地存儲以及延時投遞等
Message Receipt[XEP-00184]
客戶端層面確認消息是否已經送達
Message Archiving[XEP-0136]
在服務器上存儲消息,而不是在客戶端機器上存儲
Service Discovery
咱們須要知道系統中有哪些實體,以及該實體支持哪些服務,爲了完成這些操做,引入了實體發現和服務發現的概念。
Using Service Discovery with Servers and Services
服務發現一樣適用iq-get的disco#items/disco#info這兩個查詢操做,只是將查詢是服務而非實體。
具體的查詢步驟較爲複雜。
Using Service Discovery with Clients
Explicit Service Discovery
這種場景應用於用戶的花名冊向用戶返回是否在線的信息,這種判斷是否在線的信息帶有Full JID,所以能夠經過disco#info/disco#item來查詢。
可是這種查詢可能返回某個Full JID攜帶的所有信息,致使數據量過大,所以引入了下面的方式
Entity Capabilites: Service Discovery Shorthand
是對上面方法的改進,經過將實體支持的特性HASH爲一組特徵嗎,客戶端接收該特徵碼後與本地存儲進行比較,若是已有該特徵碼,則能夠得到支持的特性列表;若是客戶端沒有緩衝該特徵碼,則從新發送disco#info消息獲取,並緩存。
採用此種方法能夠節省響應的資源。
而且經過presence節就能夠獲取客戶端支持的功能了。
Data Forms
相似於HTML的表單,有工做流的特徵,能夠實現用戶驗證碼輸入和確認等功能。
由[XEP-0004]定義。
Multi-Party InteractionMCU 基礎多人聊天最初被稱爲groupchat,後來的迭代版本改進爲Multi-User Chat(UMC)[XEP-0045]。MCU的基本思想是用戶加入到一個聊天室,而聊天室會組播消息,聊天室起到消息反射器的做用聊天室有以下特徵3.1 消息在全部的參與者中共享3.2 全部的參與者都有一個room roster3.3 參與者都使用其nickname標識,而不是實際的JabberID3.4 房間共享參與信息3.5 參與者不只限於人,也能夠是服務等聊天室有其本身的JID,且該JID是服務器的一個組件,所以具備不一樣的域,如服務器的域稱爲:wonderland.lit,組件的域爲conference.wonderland.lit,實現MCU須要相應的組件,服務器根據域的不一樣將消息路由到對應的組件上處理。加入聊天流程5.1 用戶發送presence消息5.2 聊天室向成員廣播該presence5.3 聊天室向用戶發送成員的presence5.4 聊天室向用戶發送一些歷史消息好讓用戶參與討論,消息數目可配置,且消息帶有時間戳5.5 以後的聊天消息再也不攜帶時間戳5.6 聊天室之間的消息往來,消息類型爲groupchat若是用戶向聊天室的成員發送消息,消息類型爲chat,但消息實際上使用用戶發送給聊天室的,聊天室會改寫from/to字段爲實際接受者的JID。若是離開聊天室則會發送退席消息
成員管理
羣組中有多重角色,不一樣的角色擁有不一樣的權限,能夠將用戶臨時踢出,或加入黑名單等。
具體有: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還能夠傳輸地理信息,文件和進行遠程調用等。
Publish/Subscribe
實際上就是消息系統中的推模式,主要分三個步驟完成:首先訂閱一個主題;其次發佈一個消息;最後消息被推送到訂閱客戶端。[XEP-0060]
Subscriptions
訂閱者須要訂閱一個源,發佈者也將消息發佈到這個源。
流程:
用戶發送訂閱請求
服務器響應該訂閱請求
若是成功則能夠接收消息了,若是失敗,則有多是要求更多的配置信息
訂閱者對訂閱進行配置(可選)
訂閱者請求配置項
源返回訂閱配置表單
用戶解除訂閱
服務器返回解除訂閱響應
Publishing and Receiving Notifications
主要分爲兩個部分。
發佈方發佈消息到源;服務器將源的消息經過message的形式投遞給訂閱方。
須要注意的是:發佈方只負責將消息推送至源,投遞的邏輯由訂閱方的服務器完成。
Payloads
用戶能夠選擇是否在通知中攜帶payloads,如通知中包含頭像信息時,只須要metadata,無需具體的數據。
是否啓用payload能夠經過配置項deliver_payloads來實現。
Items
是否保存items也是能夠配置的,能夠經過persist_items配置。
保存/不保存數據的node分別稱爲persistent nodes/transient node。
Discovering Nodes
nodes及其服務能夠經過disco#info/disco#item來查詢
返回的結果能夠經過以上兩個命令進一步查詢,直到找到想要訂閱的node。
Personal Eventing
若是用戶想訂閱某個好友的動態,可使用用戶的JID做爲datanode,相應的簡化協議稱爲PEP[XEP-0163](Personal Eventing Protocal)。
用戶能夠應用PEP協議,在本身的Presence消息中包含本身的愛好信息,服務器收到該presence後,將會根據此愛好向用戶推送好友的動態。
包括User Tune,User Location,User Activity,User Mood,User Nickname,User Avatar等。
Design Decision
儘可能不要修改XMPP的核心協議,而是應該試着經過新的namespace去擴展它
因爲presence佔用了大約90%的數據流量,須要控制presence節中的數據
須要儘可能簡化XMPP客戶端的設計,尤爲是須要減小對服務器端的壓力
儘可能重用已有協議,而不是從新設計一個