Extensible Messaging and Presence Protocol (XMPP) 的實現

本文轉自:http://www.ibm.com/developerworks/cn/xml/x-xmppintro/#major1  html

如想詳細瞭解,請參照原文node

內容目錄數組

  • XMPP 架構
  • XMPP 中的地址
  • XMPP 協議
  • 使用 Ruby 的 XMPP 示例
  • XMPP 的應用
  • 多語言的 XMPP
  • 結束語

  即時消息傳遞(IM)在臨時 Internet 用戶和業務用戶中都是一個受歡迎的應用程序。它不只爲用戶提供了與他人進行實時通訊的方法,還可以獲得他們的到場信息(在線、離開、離線,等等)。Jabber 是最先的開放 IM 協議之一,由 Jeremie Miller 開發並於 1998 年做爲一個非標準 IM 協議出現。因爲 Jabber 是使用 XML 建立的可擴展協議,它很快就建立了其餘可用做通用傳輸或面向消息的中間件(MoM)的應用程序。最終由 Jabber 產生了 XMPP,這是一個 IETF 工做組協議文檔形式的基於標準的協議:RFC 3920,「可擴展消息傳遞和到場協議(XMPP)」。安全

  XMPP 並非唯一的通用消息傳遞協議。其餘受歡迎的協議(如 XML-RPC 和 SOAP)可以爲這個功能提供函數調用(如語義)。一些較新的方法,如具象狀態傳輸(ReST),使用 URL 指定位置、對象和方法,提供受控制的文件訪問。ruby

 

XMPP 架構服務器

  XMPP 與其餘的應用層協議(如SMTP)有着類似之處。在這些架構中,具備唯一名稱的客戶機經過相關的服務器與另一個具備唯一名稱的客戶機進行通訊。每一個客戶機執行客戶機的協議表單,而服務器在表單中提供路由功能。圖 1 說明了這個簡單的架構。在這個例子中,每一個客戶機都是同一個域名(discovery.nasa.guv)的一部分。網絡

圖 1. 由一個服務器和兩個客戶機組成的簡單的 XMPP 架構

 

  服務器還能夠針對不一樣域之間(例如,在 discovery.nasa.guv 和 europa.nasa.guv 之間)的路由進行通訊。此外,網關可用於在外部消息傳遞域和協議之間進行轉換。圖 2 中的示例顯示了一個 XMPP 網絡,網關通往一個短信服務(SMS)域和一個 SMTP 域。在這種狀況下,網關大多數都是被用來在 IM 協議(例如,在 XMPP 和 Internet 中繼聊天(IRC))之間進行轉換。做爲一個可擴展的協議,XMPP 對於在不一樣的端點協議間提供統一鏈接性來講是一個理想的中樞協議。XMPP 網關容許終止一個給定的客戶端到服務器的會話,而且向目標端點協議發起一個新的會話(同時進行必要的協議轉換)。架構

圖 2. 包含了 XMPP 網關的更爲複雜的 XMPP 架構

 

XMPP 中的地址框架

XMPP 中的地址(即 Jabber ID[JID])與標準電子郵件地址類似,但有着幾個顯著的差異。JID 包含一個可選節點、一個域和一個可選資源:dom

[ node "@" ] domain [ "/" resource ]

 

最多見的用法就是定義一個 IM 用戶(相似電子郵件地址),好比 DavidBowman@discovery.nasa.guv。用戶可以屢次登陸 XMPP 服務器,而在這個例子中,資源可以表示位置。例如,示例用戶可能有一個主終端(DavidBowman@discovery.nasa.guv/terminal)JID 和另一個來自 EVA pod(DavidBowman@discovery.nasa.guv/eva_pod1)的 JID。所以,可以找到某個特定位置,或離開此位置並找到用戶,無論用戶在哪一個位置登陸。

XMPP 協議

XMPP 是一個相對簡單的協議,它經過 XML 消息出如今 TCP 套接字上。異步通訊發生在 XML 流中,並帶有 XML 節(stanza)。XML 流 是封裝了兩個實體間的 XML 信息交換的容器。XML 流傳遞 XML 節,這些 XML 節是一些分散的信息單元。例如,在 XMPP 中使用 XML 節傳遞消息(IM 用戶間的文本)以及到場信息。爲說明這些概念,請看一個在兩個客戶端之間使用 XMPP 進行 IM 通訊的簡單示例。

圖 3 演示了兩個實體之間的簡單會話。注意,至少有一個服務器會出如今會話中(在這個例子中,由於兩個客戶端存在於同一個域中,因此準確地說,只有一個服務器)。在 圖 3 中,左邊的客戶端是發起實體(發起兩個實體間的 XMPP 通訊)。XML 流使用 to 屬性來識別接收域(以及定義 XML 名稱空間)。右邊的接收客戶端 接收 XML 流並使用 XML 流響應(在這個例子中,使用 from 屬性)進行迴應。在這個階段,能夠進行幾個不一樣的協商(如驗證和加密)。請忽略這部分討論(例外狀況是當 IM 客戶端出如今不一樣的域中進行服務器到服務器通訊)。(請查看 圖 3 的文字版本。)

圖 3. 示例(簡化的)XMPP 通訊

圖 3 中的 XML 流的下一步是進行消息傳遞。這個通訊在消息節中進行,而且包括了源和目標 XMPP 地址(from 和to)、使用的語言以及節正文中的消息。對方用其本身的消息進行響應,關鍵區別是源和目標 XMPP 地址。最後,發出流關閉消息(在鏈接的兩端進行)以關閉 XML 流。

任何一邊均可能返回一個錯誤,以下面所定義。在本例中,對方發送了一個無效的 XML 流和節。

<stream:error>
  <xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
<stream:error>

 

儘管這個示例展現了簡單的 IM 通訊,但很容易就能瞭解消息節是如何轉換成 RPC 消息的,同時負載了來自對等協商的安全問題。您能夠把函數註冊爲節點,以建立一個動態的 Web 服務框架,而不是對域中的用戶進行註冊。如今讓咱們看一下如何建立一個在 XMPP 中通訊的簡單應用程序。

使用 Ruby 的 XMPP 示例

選擇 XMPP 庫

XMPP 其餘有趣方面的其中之一就是您能夠在大量的庫中進行選擇,包括各類各樣的語言。這個示例使用了 Ruby 語言和 XMPP4R 庫。要獲取現有的各類庫的連接,請查看 參考資料

經過庫來演示 XMPP,探究用做技術字典的簡單 IM 代理的開發。使用這種方法,您經過一個標準的即時消息程序輸入一個詞時,IM 代理將返回它的定義。

本示例實現了能夠經過 XMPP 鏈接到其餘 IM 代理的 IM 代理,而且一旦鏈接成功,將解釋詞語的定義。清單 1 提供了簡單的 XMPP 代理。


清單 1. 用於文字定義的簡單 XMPP 代理

				
require 'xmpp4r/client'

# Create a *very* simple dictionary using a hash
hash = {}
hash['ruby'] = 'Greatest little object oriented scripting language'
hash['xmpp4r'] = 'Simple XMPP library for ruby'
hash['xmpp'] = 'Extensible Messaging and Presence Protocol'

# Connect to the server and authenticate
jid = Jabber::JID::new('bot@default.rs/Home')
cl = Jabber::Client::new(jid)
cl.connect
cl.auth('password')

# Indicate our presence to the server
cl.send Jabber::Presence::new

# Send a salutation to a given user that we're ready
salutation = Jabber::Message::new( 'hal@default.rs', 'DictBot ready' )
salutation.set_type(:chat).set_id('1')
cl.send salutation 

# Add a message callback to respond to peer requests
cl.add_message_callback do |inmsg|

    # Lookup the word in the dictionary
    resp = hash[inmsg.body]
    if resp == nil
      resp = "don't know about " + inmsg.body
    end

    # Send the response
    outmsg = Jabber::Message::new( inmsg.from, resp )
    outmsg.set_type(:chat).set_id('1')
    cl.send outmsg

end

# Run
while 1
end

 

清單 1 首先建立了一個簡單的字典。爲此,您可使用 Ruby 中的 hash 類,它容許您建立鍵值對(相似於數組),可是隨後能夠輕鬆地經過鍵引用它們。接下來,使用 XMPP4R 庫鏈接到服務器。首先使用 Client 類建立一個 JID 和一個新的客戶端鏈接。要真正鏈接到 IM 服務器,請使用 connect 方法。一旦鏈接上了,您可使用密碼來調用 auth 方法。如今,鏈接已經能夠用來傳遞消息了。

下一步(可選)是表示您已經登陸了 IM 服務器。爲此,須要向服務器發送一個 presence 節。您還能夠發送一個可選信息給對方,告訴對方您已在線了。這點能夠經過建立一個消息節並使用對方地址和消息對它進行初始化來實現。消息初始化成功後,能夠經過對 Client 類實例使用 send 方法來發送它。

要對發送給您的消息做出反應,請使用您的客戶端鏈接的 add_message_callback 方法。任什麼時候候消息到達時,都將調用代碼塊來處理消息。傳入消息表示爲 inmsgMessage 實例)。首先要進行檢查,看看傳入消息 body 定義的詞是否在您的字典中。若是返回 nil,那麼表示沒有找到該詞,所以您須要提供一個默認的響應。使用傳入消息(inmsg.from)和響應字符串建立一個新的消息。初始化完成後,經過客戶端實例把新消息發送給發送方。

圖 4 顯示了應用程序的一次運行。本示例使用了受歡迎的 pidgin 通用聊天客戶端。pidgin 客戶端支持全部主要的聊天協議,並能夠與許多現有的聊天網絡一塊兒使用(甚至是同步進行)。圖 4 顯示了當 IM 代理鏈接到服務器並與定義用戶開始會話時建立的消息傳遞彈出窗口。


圖 4. 使用 IM 代理的示例 IM 會話
使用 IM 代理的示例 IM 會話的屏幕截圖 

這個應用程序本來很是簡單,可是 XMPP4R 爲其餘的功能(如賬戶註冊、發現、文件遷移、多用戶聊天、發佈/訂閱,甚至 RPC)提供了許多類和方法。您能夠在 參考資料 中找到一個 「可瀏覽的」 類 API,它爲查看全部的 XMPP4R 文件、類和方法提供了一個方便的方法。

 

XMPP 的應用

XMPP 爲網絡中的消息傳遞提供了一個通用框架。除了傳統的 IM 和到場數據分佈外,XMPP 還能夠用於許多不一樣用途。

IM 的封閉式應用包括小組或多方消息傳遞,或開發多用戶聊天室。使用多方通訊,能夠實現與 Twitter 提供的微博客(micro-blogging)相似的功能。可是文本並非唯一能夠經過 XMPP 傳送的數據。其餘的通訊形式包括聲音、圖片和視頻數據。

現在出現了服務發現協議(好比 Bonjour 或 Service Location Protocol),但 XMPP 爲網絡中的服務發現以及服務與功能的宣傳提供了堅實的基礎。

在線遊戲大量地使用了 XMPP。XMPP 爲在線遊戲提供了一組關鍵的功能,包括驗證、到場信息、聊天,以及可擴展的遊戲狀態信息的接近實時的交流。

最後,XMPP 是新的雲計算時代的一個完美協議。雲計算和存儲系統依賴不一樣層次和形式的通訊,不只包括在系統間進行消息傳遞以中繼狀態,還包括較大對象(如存儲或虛擬機器)的遷移。經過結合身份驗證和傳輸中的數據保護,XMPP 能夠應用在不一樣的層次,並且能夠做爲一個理想的中間件協議。

在此請注意,大多數應用與人類通訊沒有任何的關係,而是關係到機器通訊(MMI 或機器到機器的通訊)。當您發現用於 IM 的協議有着各類各樣的用途時,您會以爲這是很是有趣的事情。


多語言的 XMPP

XMPP 是做爲一組庫實現的,爲應用程序提供了 XMPP 能力。從 XMPP 支持衆多語言這點就能輕鬆判斷出,XMPP 是一種很是有用的協議。您將發現 XMPP 庫軟件支持傳統語言(如 C 和 C++)以及受歡迎的腳本語言(如 Ruby、Java™ 語言、Python、Perl 和 Tcl)。您還將發現 XMPP 庫支持其餘一些語言,如 Erlang、C# 和 Lisp。所以,無論您在何種環境中,都有可能找到一種 XMPP 庫來訪問 XMPP。要得到各類 XMPP 庫支持的語言列表,請查看 參考資料

 

結束語

不斷成長的 ReST

儘管 ReST 是一個架構模型而非實現方法,但它在一些領域中成長得很快。ReST 的用於遠程資源管理的簡單模型已經存放在了雲存儲中,在那裏,ReST 被用做存儲訪問和管理模型。

許多有用的技術經常以全新的方式使用,這些方式是技術建立者當初從未考慮過的。例如,HTTP 是服務於 Internet 上的 Web 頁面的事實標準協議,但它同時也用做針對 SOAP 和 XML-RPC 等其餘協議(包括 ReST 之類的協議模型)的應用層傳輸。XMPP 是另一個發掘出除了 IM 外的其餘許多新應用的有用技術。您將如何把 XMPP 引用到您的解決方案中呢?

相關文章
相關標籤/搜索