XMPP 和 OpenFire

XMPP

XMPP(可擴展消息處理現場協議)是基於可擴展標記語言(XML)的協議,它用於即時消息(IM)以及在線現場探測。是一種數據傳輸協議。
XMPP的前身是Jabber,一個開源形式組織產生的網絡即時通訊協議。html

XMPP 地址格式

一個XMPP節點的惟一標示符jabber identifier(JID),即實體地址,用來表示一個Jabber用戶,可是也能夠表示其餘內容,例如一個聊天室.node

一個有效的JID包括一系列元素:segmentfault

  • (1)域名(domain identifier);
  • (2)節點(node identifier);
  • (3)源(resource identifier).

它的格式是 node@domain/resource,node@domain,相似電子郵件的地址格式.服務器

  • domain用來表示接點不一樣的設備或位置,這個是可選的,例如a在Server1上註冊了一個用戶,用戶名爲doom,那麼a的JID就是 doom@serverl,在發送消息時,指明 doom@serverl 就能夠了,
  • resource能夠不用指定,但a在登陸到這個Server時,fl的JID多是 doom@serverl/exodus (若是a用Exodus軟件登陸),也多是 doom@serverl/psi (若是a用psi軟件登陸).資源只用來識別屬於用戶的位置或設備等,一個用戶能夠同時以多種資源與同一個XMPP服務器鏈接。

 

XMPP 協議的 XML 格式:

image

這裏有三個頂級 XML 元素: Presence、Message、IQ,每一個的含義以下:網絡

<Presence> 用來代表用戶的狀態,

如:online、away、dnd(請勿打擾)等。當用戶離線或改變本身的狀態時,就會在stream的上下文中插入一個Presence元素,來代表自身的狀態. 架構

<Message> 用於在兩個jabber用戶之間發送信息。

Jsm(jabber會話管理器)負責知足全部的消息,無論目標用戶的狀態如何。若是用戶在線jsm當即提交;不然jsm就存儲。dom

To :標識消息的接收方。
from : 指發送方的名字或標示(id)o
Text: 此元素包含了要提交給目標用戶的信息。分佈式

 

< IQ > 一種請求/響應機制,

從一個節點從發送請求,另一個節點接受請求,並進行響應.
例如,client在stream的上下文中插入一個元素,向Server請求獲得本身的好友列表,Server返回一個,裏面是請求的結果.ide

<iq > 主要的屬性是type。包括:
Get :獲取當前域值。
Set :設置或替換get查詢的值。
Result :說明成功的響應了先前的查詢。
Error: 查詢和響應中出現的錯誤。測試

 

XML流


XMPP本質上是一種XML流技術。

客戶端開始和XMPP服務器會話,會打開一個長時間的TCP鏈接,而後和服務器協商一個流。
一旦你和你的服務器創建了一個XML流,你和你的服務器能夠經過流交換三個特殊的XML片斷:<message/>,<presence/>,<iq/>.這些片斷稱爲XML節。並且一旦你已創建一個XML流,你能夠經過流發送無數個節。

下圖是 C 客戶端  S 服務器端 XML流的精簡內容:

C:  <stream:stream>
C:  <presence/>
C:  <iq type="get">
           <query xmlns="jabber:iq:roster"/>
    </iq>
S:  <iq type="result">
           <query xmlns="jabber:iq:roster">
            <item jid="suke@skh.whu.edu.cn"xs/>
            <item jid="gmz@skh.whu.edu.cn"/>
            <item jid="beta@skh.whu.edu.cn"/>
        </query>
    </iq>
C:  <message from="suke@skh.whu.edu.cn" 
              to="beta@skh.whu.edu.cn">
           <body>Off with his head!</body>
    </message>
S:  <message from="lj@skh.whu.edu.cn"
              to="cyl@skh.whu.edu.cn ">
           <body>You are all pardoned.</body>
    </message>
C:  <presence type="unavailable"/>
C:     </stream:stream>

 

XMPP面臨的問題:

    • XMPP是基於穩定長鏈接網絡環境所設計的,對於不夠穩定和帶寬小的移動網絡不是很是合適。
    • 因爲XMPP基於XML,因此流量大,流量問題對於移動網絡來講很是敏感,而後就是消息不可靠、CMWAP兼容、開源項目對協議實現不完善等問題,也是XMPP面臨的問題。

數據負載過重:隨着一般超過 70%的 XMPP 協議的服務器的數據流量的存在和近60%的被重複轉發,XMPP 協議目前擁有一個大型架空中存在的數據提供給多個收件人。新的議定書正在研究,以減輕這一問題。

沒有二進制數據:XMPP 協議的方式被編碼爲一個單一的長的 XML 文件,所以沒法提供修改二進制數據。所以, 文件傳輸協議同樣使用外部的 HTTP。若是不可避免,XMPP 協議還提供了帶編碼的文件傳輸的全部數據使用的 Base64。至於其餘二進制數據加密會話(encrypted conversations)或圖形圖標(graphic icons)以嵌入式使用相同的方法。

XMPP 優化的一個方案是:

  • XML經過精簡壓縮來實現流量可控。
  • 消息的不可靠能夠經過擴展XMPP來實現ACK

 

OpenFire

 

Openfire是XMPP領域最知名的開源項目,它簡單易用,是不少團隊的首選方案,這是國內使用最多的開源方案。Openfire雖然優勢不少,可是缺點也很多,最致命的就是它的分佈式擴展能力很弱,當用戶量很大的時候,水平擴展就成爲它的瓶頸所在。

 

消息握手

常常會有人發現,Openfire的兩個客戶端,在網絡不穩定的狀況下,會丟失消息。起初我也不知道到底發生了什麼,直到後來,在測試中發現,當你用鏈接上通信服務器後,直接拔了路由器,wifi異常斷開,客戶端與Server沒辦法握手告知TCP斷線的事情,因此你會在一段時間內,服務器認爲你在線,而實際你離線。這種狀況在地鐵、快速移動切換網絡基站的狀況下也常常有復現。此時Openfire收到關於你的消息會直接推送給你,而你此時又由於沒有網絡收取不到,因此消息丟失。

解決辦法:消息進行握手,每條消息發給客戶端,都須要客戶端回覆回執,不然一直保存在服務器。

心跳機制

由於上述問題,因此就要常常清理那些失效客戶端,保證客戶端和服務器狀態同步。

如每15s - 60s 客戶端定時發送一個小型的msg給服務器,服務器收到後回覆一個callback。

若是服務器120s內沒有收取到任何消息,那麼close Session。

 

 

 

雖然XMPP有不少弊端,可是它的生態目前是最完善的,若是從成本角度來考量,XMPP是前期投入最小產出最快的。可是若是是搭建一個SAAS平臺或者千萬量級的IM,XMPP就不是最優的選擇了。

 

 

 

參考資料:

漫談IM通訊架構
http://www.yangguo.info/2015/08/17/%E6%BC%AB%E8%B0%88%E9%80%9A%E8%AE%AF%E6%9E%B6%E6%9E%84/ 

 

開源移動通信架構與XMPP
http://timyang.net/im/mobile-im-xmpp/ 

xmpp協議詳解一:xmpp基本概念
http://www.jianshu.com/p/a94749385755 

即時通信協議的選型之XMPP
http://www.biaodianfu.com/xmpp.html 

XMPP 協議適合用來作移動 IM 麼?
http://www.javashuo.com/article/p-wlrgvmnd-bn.html 

http://www.mikewootc.com/wiki/net/protocol/xmpp.html

相關文章
相關標籤/搜索