1. 程式人生 > >Openfire分析之一:Openfire與XMPP協議

Openfire分析之一:Openfire與XMPP協議

插件 問題 帳號 body 通訊 binding mil star mina框架

  引言

  上帝說,要有光,於是就有了光。

  有點玄。

  如果將時光回溯無數歲月,到幾百萬年的蠻荒時代,人類史上第一次發生信息交換,會是什麽樣子?是轉一下腦袋,還是眨一下眼?

  但不管是什麽形式,於是有了信息,有了通信。而後幾百萬年的時代變遷物種生滅,以及後來古文明時代、封建社會、再到如今的互聯網時代,不管是峰煙戰火,還是市井喧囂,都充斥著各式各樣的信息,每個角落都無時無刻的發生著信息交換。信息交換的載體,從以前可能揮下手勢、到如今全球高速網絡信道….

  信息在這個世界裏,扮演著一個什麽樣的角色,是人在控制信息?還是信息在控制著人?

  有點玄,但好在這些都不是我們接下去所要討論的問題,所以留著給哲學家去思考。

  我們今天所要講的內容,其實是計算機世界裏,即時通信的信息交換,準確的來說,是其中一種。

  信息能完成交換,需要的先決條件是什麽?自然是雙方要能”懂”,就是所謂的協議。協議一致雙方才能互相get到點。

  目前互聯網產品使用的即時通信協議有這幾種:即時信息和空間協議(IMPP)、空間和即時信息協議(PRIM)、針對即時通訊和空間平衡擴充的進程開始協議SIP(SIMPLE)以及XMPP。PRIM與XMPP、SIMPLE類似,但已經不再使用了。

  本次要講的是XMPP,由Openfire實現,OK,廢話說了不少,開始吧。

  1、Openfire與XMPP

  Openfire是開源的實時協作服務器(RTC),它是基於公開協議XMPP(RFC-3920),並在此基礎上實現了XMPP-IM(RFC-3921),擴展了IM功能,對實施協作的各種場景做較全面的考慮,如用戶在線狀態切換、消息訂閱、通知等等,因此可以用來搭建即時通信服務器,其搭建的方法也很簡易。

  RFC-3920與RFC-3921的說明:

  (1)RFC-3920:XMPP的核心。定義了XMPP協議框架下應用的網絡架構,引入了XMLStream(XML流)與XMLStanza(XML節),並規定XMPP協議在通信過程中使用的XML標簽。使用XML標簽從根本上說是協議開放性與擴展性的需要。此外,在通信的安全方面,把TLS 安全傳輸機制與SASL 認證機制引入到內核,與XMPP進行無縫的連接,為協議的安全性、可靠性奠定了基礎。Core文檔還規定了錯誤的定義及處理、XML 的使用規範、JID(Jabber Identifier,Jabber 標識符)的定義、命名規範等等。所以這是所有基於XMPP協議的應用都必需支持的文檔。

  (2)RFC-3921:用戶成功登陸到服務器之後,發布更新自己的在線好友管理、發送即時聊天消息等業務。所有的這些業務都是通過三種基本的XML 節來完成的:IQ Stanza(IQ 節), Presence Stanza(Presence 節), Message Stanza(Message 節)。RFC3921 還對阻塞策略進行了定義,定義是多種阻塞方式。可以說,RFC3921 是RFC3920的充分補充。兩個文檔結合起來,就形成了一個基本的即時通信協議平臺,在這個平臺上可以開發出各種各樣的應用。

  2、Openfire的特點:

 (1)超強的擴展能力

  XMPP協議,繼承了在XML靈活的擴展性,通過擴展發送擴展信息、或者在原有的信息中增加擴展節點來處理用戶需求。另外,Openfire本身也支持插件開發,開發者可以根據需求,以插件的形式添加所需要的功能,例如好友列表、群成員列表等,而不需要去修改核心的源代碼。

(2)並發能力

  Openfire的通信處理基於Apache MINA框架實現,單機可支持上萬的並發,同時也支持集群。

(3)安全性:

  XMPP在C2S通信,和S2S通信中都使用TLS協議作為通信通道的加密方法,保證通信的安全

(3)對Web的支持:

  Openfire采用內置的jetty作web服務器,可以方便的在上面增加WEB功能。jetty服務器是隨AdminConsolePlugin插件時啟動,通過調用startup()方法。9090為其明文端口,9091為其加密端口。

  3、通信機制

  1、帳號體系

  (1)XMPP服務器的帳號基礎,是域(Domain),例如:org.example.com,它在服務器配置時的時候設置,也是服務器能被訪問到的域名或IP地址。客戶端連接的時候,用這個域去尋找服務器。

  (2)JID:XMPP中,任何一個可能進行通信的實體,包括一個用戶、或者一個聊天室,都需要一個JID。

  用戶的JID格式為:[email protected],如:[email protected]

  聊天室的JID為:[email protected], 如[email protected]

  一般情況,JID後面還會附帶一個資源名(resource),指代這個客戶端的來源,比如:[email protected]/pc-abc,表示這個JID在一臺名為pc-abc的設備上登錄。這是同一個帳號能夠在多個設備中登錄的基礎。

  2、通信端口

  C-S連接的端口是5222 ,S-S連接的端口為5269,這些端口已經在IANA註冊。

  3、通信機制

  當客戶端連接上XMPP服務器創建會話時,首先是建立一個TCP長連接,並在這個連接上收發XML流進行協商,協商通過後,服務端與客戶端,可以通過Message、Presence、IQ這三種格式進行數據交換。

  這三種數據交換格式,下面逐個做介紹:

  (1)Message:用於在兩個客戶端之前發送信息。

  結構如下:

<message from=‘[email protected]‘ to=‘[email protected]‘ xml:lang=‘en‘>
    <body>Are you OK?</body>
</message>

  其中:

  To : 消息接收方JID。

  from : 消息發送方JID

  body: 所要發送的消息。

  (2)Presence:用來表明用戶的狀態,當用戶離線或改變自己的狀態時,就會在stream的上下文中插入一個Presence元素,來表明自身的狀態.

  結構如下:

<presence from=‘[email protected]‘ to=‘[email protected]‘>
    <status> Online </status>
</presence>

  (3)IQ:一種請求/響應機制,類似於Http的get請求。

  結構如下:(以客戶端請求服務器綁定資源為例)

<iq type=‘set‘ id=‘bind_1‘>
     <bind xmlns=‘urn:ietf:params:xml:ns:xmpp-bind‘/>
</iq>

  iq消息中,type是主要屬性,值包括:

Get :獲取當前域值。
Set :設置或替換get查詢的值。
Result :說明成功的響應了先前的查詢。
Error: 查詢和響應中出現的錯誤。

  4、通信示例

  下面以一個簡單的例子,說明客戶端與服務的交互過程:

  (1) 客戶端發起請求連接

<?xml version=‘1.0‘?>
  <stream:stream to=‘example.com‘ xmlns=‘jabber:client‘ xmlns:stream=‘http://etherx.jabber.org/streams‘ version=‘1.0‘>

  (2) 服務端進行驗證、資源綁定等

<?xml version=‘1.0‘?>
  <stream:stream from=‘example.com‘ id=‘someid‘ xmlns=‘jabber:client‘ xmlns:stream=‘http://etherx.jabber.org/streams‘ version=‘1.0‘>
        ...  encryption, authentication, and resource binding ...

  (3)客戶端開始發送消息

<message from=‘[email protected]‘ to=‘[email protected]‘ xml:lang=‘en‘>
        <body>Art thou OK?</body>
</message>

  (4) 服務端響應
  這裏其實是省略了一個客戶端。完整來看,應是服務器與romeo進行一次交換之後,再將數據返回給juliet,但為了說明通信流程,將中間另一端省略掉。

 <message from=‘[email protected]‘ to=‘[email protected]‘ xml:lang=‘en‘>
        <body>I‘m fine!</body>
</message>

  (5)客戶端通信結束

</stream:stream>

  (6)服務端通信結束

</stream:stream>

  可以看到,一次完整的通信,需要經過六個步聚。

  關於XMPP的其他信息,可以網上查閱資源了解,這裏不再贅述。

  

  後面的章節,將一步步的從Openfire的源代碼入手,分析整套系統的運行機制,望對讀者有幫助。


  over!

Openfire分析之一:Openfire與XMPP協議