XMPP(Extensible Messaging and Presence Protocol,前稱Jabber)是一種以 XML 爲基礎的開放式實時通訊協議,關於它的協議細節,網上已經有太多分析文章,我這裏就再也不贅述(並且,我也不可能比別人解釋的更清楚)。簡單來看這個協議,咱們只須要知道:node
1,XMPP 的三種基本角色:客戶端、服務器和網關,通訊可以在這三者的任意兩個之間雙向發生。服務器端同時承擔了客戶端信息記錄、鏈接管理和信息路由的功能。網關則承擔着與異構系統的互聯互通功能。在 RFC 3920 XMPP Core 中對 XMPP 網絡結構有一個描述:程序員
C1----S1---S2—C3 | C2----+--G1===FN1===FC1
這裏 C1,C2,C3 表示 XMPP 客戶端;S1,S2 表示 XMPP 服務器;G1 表示網關,用來負責 XMPP 協議和外部聊天協議的轉換;FN1 表示外部消息網絡的服務器,FC1 表示外部網絡客戶端。sql
你們可能會奇怪,這裏爲何須要一個網關呢。這要從 XMPP 的來源提及。1996 年 Mirabilis 公司推出了世界上第一個即時通訊系統 ICQ,不到 10 年,IM 就成了最流行的應用之一,MSN、Gtalk、雅虎即時通、AIM、Adium、Pidgin 等各類軟件如雨後春筍般涌現,可是這些服務之間沒有統一的標準,不能互聯互通,XMPP 的設計目的就是爲了實現整個及時通訊服務協議的互通,讓 IM 成爲繼 WEB 和 Email 以後的互聯網第三大服務。數據庫
2,XMPP 的消息格式。服務器
XMPP 協議的全部消息都是 XML 格式的,這是 XMPP 協議的另外一個充滿歷史意味的選擇,想當年 SOA / SOAP 一時間爆發起來,不少消息交換協議都採用了 XML 格式,可是不想 XML 很快就成了「大數據」的代名詞。在 RFC 3920 XMPP Core 中定義了兩個基礎概念,XML Stream 和 XML Stanza,XML Stream 是兩個節點之間進行數據交換的容器,它定義了頂層的XML節點
2.1 Presence
用於肯定用戶的狀態。消息結構舉例以下(每一個 XML 的 node 還會有不少其餘 attribute,爲了簡單起見這裏省略,下同):session
<presence from="abc@jabber.org/contact" to="def@jabber.org/contact"> <status>online</status> </presence>
2.2 Message
用於在兩個用戶之間發送消息。消息結構舉例以下:併發
<message from="abc@jabber.org/contact" to="def@jabber.org/contact" type=「chat」> <body>hello</body> </message>
2.3 IQ
信息/請求,是一個請求-響應機制,管理XMPP服務器上兩個用戶的轉換,容許他們經過相應的XML格式進行查詢和響應。app
<iq from="abc@jabber.org/contact" id=「id11」 type=「result」> </iq>
3,XMPP 的交互流程。
XMPP 經過 TCP 傳輸了什麼內容?在 QQ 裏面,消息是使用二進制形式發送的,在 MSN 裏面是採用純文本指令加參數加換行符的形式發送的,而 XMPP 傳輸的即時通信指令與他們相仿,只是協議的形式變成了 XML 格式的純文本,這讓解析更容易,方便了開發和查錯,可是也帶來了數據負載太重的缺點,而被人廣爲詬病。性能
XMPP 聊天的過程以下:
XMPP 協議的最主要的一點就是開放,不論是協議、客戶端,仍是 Server 端,都有成熟的實現方案。爲了實際感覺 XMPP 協議的聊天過程,我使用 asmack library + OpenFire 服務器搭建了一套完整的測試環境。
OpenFire 採用 Java 開發,是一個基於 XMPP 協議 的開源的實時協做服務器,它的安裝和使用都很是簡單,自帶有一個內置的存儲數據庫(固然,你也可使用獨立數據庫如Mysql等),並利用 Web 進行管理。其餘相似的開源系統還有不少,eJabber、Tigase 也常常被用到。可是根據咱們以前的經驗,這些開源系統能支持的併發鏈接數都不高,要是有超過10萬的用戶同時連上來,對它們來講就快達到單機的瓶頸了,這時候通常都須要水平拆分,可是拆分以後服務器之間的 session 同步負擔會大幅加劇,對於性能又帶來不小的抵消。因此這些系統大都被拿來作研究和測試用,不多見到大規模在生產環境中使用的。
好吧,咱們仍是來實際聊聊看。爲了體現真實性,選取了程序員圈子裏面較大機率可能發生的幾段典型對話:
實際結果以下,我在 Nexus5 上面運行一個 IM app,鏈接上我本身搭建的 openfire 服務器,而後模擬了上面幾段對話,在幾個參與者的前提下,消息實時性還挺好,但在系統設置-》網絡流量中看到,整個聊天過程當中該 app 消耗掉的網絡流量高達 36KB,聊天記錄的文本文件大小爲 8KB,也就是說網絡流量的 70% 都消耗在 XMPP 協議層了,這個數字正好吻合了維基百科上吐槽的數據冗餘率。
最後測試下來看,我我的感受是,對於移動互聯網來講,省電、省流量是全部底層服務的一個關鍵技術指標,XMPP協議看起來已經落後移動互聯網了。