基於XMPP的即時通訊系統的建立(二)— XMPP詳解

檀志文發表於2017-12-14

不好意思,內附一些swift的東西地址:github.com/tanzhiwen/S…

XMPP詳解(http://www.cnblogs.com/jiyuqi/tag/xmpp/)

XMPP(eXtensible Messaging and Presence Protocol,可擴充套件訊息處理和現場協議)是一種在兩個地點間傳遞小型結構化資料的協議。在此基礎上,XMPP協議已經被用來構建大規模即時通訊系統、遊戲平臺、協作空間及語音和視訊會議系統。

XMPP由幾個小的構造塊組成,並在此基礎上擴充套件出了更多的構造塊。XMPP中有眾多系統:釋出-訂閱服務、多人聊天、表單檢索與處理、服務發現、實時資料傳輸、隱私處理及遠端過程呼叫等。

大多數社交媒體(Facebook及Twitter)也採用了XMPP協議。

什麼是XMPP

與其他協議一樣,XMPP定義了在兩個或者更多通訊實體間傳遞資料所採用的格式。對於XMPP,實體通常是指客戶端伺服器,但是其也允許客戶端與客戶端或伺服器端與伺服器端的通訊。

在XMPP上交換的是XML資料,採用這種格式,使XMPP協議獲得了極大的可擴充套件性,因為使用XML可以方便的新增功能並保證前後向相容。使用XML較二進位制協議佔用更大的頻寬,但獲得的優勢是具有了幾乎無限的可擴充套件性。

使用者可以向XMPP Standards Foundation註冊協議擴充套件。

在XMPP中,XML資料被組織為了一對流,每個流分別對應通訊的一個方向。每個XML流均由一個開始元素、後跟XMPP節和其他頂級元素,然後是一個結束元素組成。每個XMPP節(可帶有子元素及屬性)均是該流的一級子元素。在XMPP連線末尾,這兩個流形成了一對有效的XMPP文件。

XMPP節構成了該協議的核心部分,而XMPP應用程式則關注如何傳送和響應各種型別的節。節可能包含網路上其他實體的資訊、類似於電子郵件的個人訊息或為計算機處理而設計的結構化資料。what think you of books在一個典型的XMPP會話中,一個上述的節將會從darcy的XMPP客戶端傳送到她的XMPP伺服器,她的伺服器將會注意到該節的目的地是某個遠端伺服器上的一個實體,因此與該遠端伺服器先建立XMPP連線,並將訊息轉發該處。

這種通訊網路與電子郵件類似,但與電子郵件伺服器不同的是,XMPP間的伺服器可以直接通訊,而不需要藉助中間伺服器。

這種直接通訊避免了垃圾資訊的干擾,且還支援通過TLS(Transport Layer Security,傳輸層安全)來加密通訊並通過SASL(Simple Authentication and Security Layers,簡單身份驗證與安全層)實現身份驗證機制。

XMPP使用傳遞短小資訊來設計的,而非針對大型資料塊,但XMPP能夠用來協商並建立可在端點間傳遞大型資料塊的帶內或者帶外傳輸。

XMPP網路

任何XMPP網路都是由若干角色組成,可以分為伺服器端、客戶端、元件和伺服器外掛。

XMPP網路與WWW網路及EMAIL網路不同,XMPP伺服器之間定址只會跳一次,而EMAIL協議則會有多箇中轉伺服器,XMPP儲存完整的列表。

伺服器

XMPP伺服器是任何XMPP網路的通訊系統,伺服器的任務就是為XMPP節提供路由。無論這些節是從內部的一個使用者發往另外一個使用者還是本地使用者傳送給伺服器。

一組能夠相互通訊的XMPP伺服器構成了XMPP網路。

XMPP伺服器總是允許使用者連線到自己,但是也可以編寫直接使用伺服器-伺服器協議的應用和程式,來減輕路由消耗

Ejabberd、Openfire和Tigase是三種能夠執行在Windows,Mac OS X和Linux的開源伺服器。

M-Link和Jabber XCP是商用產品。

客戶端

大多數XMPP實體均是客戶端,通過客戶端-伺服器協議連線到XMPP伺服器。

客戶端必須向某個地方的XMPP伺服器進行身份驗證。伺服器會將該客戶端傳送的所有節路由到合適的目的地。

伺服器還負責管理客戶端會話的其他幾個方面,包括花名冊及裸地址。

元件

不僅僅是客戶端能夠連線到XMPP伺服器,大多數伺服器還支援外部伺服器元件。這些元件通過新增某種新服務來增強伺服器的行為。這些元件在伺服器內有各自的身份和地址,但執行在外部並通過元件協議通訊。

元件協議(XEP-0114)可以讓開發人員以一種伺服器不可知的方式建立伺服器擴充套件,例如多人聊天服務。

元件也需要向XMPP伺服器進行身份驗證,但要較客戶端的完全SASL驗證簡單,例如口令。

每個元件程式設計伺服器內部一個可單獨定址的實體,在外界看類似於一個子伺服器。除了基本節之外,XMPP伺服器不會代替已連線元件來管理其他節的路由。

伺服器還允許元件在內部自行路由或管理節,因而更為靈活。


外掛

許多XMPP伺服器還支援使用外掛進行擴充套件,但外掛深入到伺服器內部,有較高的效率以及最低的通用性。

外掛一般是繫結特定型別的伺服器的。

XMPP定址

XMPP網路上的每個實體都有一個或多個地址(稱為JID,jabber identifier)。通常類似於:

darcy@pemberley.lit和elizabeth@longbourn.lit就是兩個JID。

JID由三個部分組成,節點、域和資源,域是必須的,其他兩個部分是可選的。

域是實體(伺服器、元件或外掛)可解析的DNS名稱。僅由域組成的JID是有效地址,表示伺服器地址。指向域的節將由伺服器自身處理,並可能被路由到某個元件或外掛。

本地部分通常用來識別域中的一個特定使用者,位於@前。本地部分也可以用來識別其他物件,如某個聊天室。

JID的資源部分通常會標識一個特定客戶端的XMPP連線。對於XMPP客戶端而言,每個連線均被指派一個資源。如darcy@perberley.lit想要連線他的書法和圖書館則可以通過

darcy@perberley.lit/study和darcy@perberley.lit/library來定址,這樣避免了使用者在開啟多個連結時訊息無法找到正確的處理器。主要注意的是,資源部分是區分大小寫的。

JID劃分為兩種型別:

  裸JID

完整JID去除資源部分的地址,客戶端的裸JID有些特殊,這是因為伺服器自己將處理髮往客戶端的裸JID節。裸JID可以視為定址使用者的賬戶,而不是客戶端。

  完整JID

最為具體的地址

XMPP節核心XMPP工具集由三個基本節組成,分別為、和XMPP流由兩份XML文件組成,通訊的每個方向均有一個文件,這些文件有一個根元素,的子元素由可路由的節以及與流相關的頂級子元素構成。複製程式碼//請求自己的花名冊//通知伺服器她已線上並可以訪問I cannot talk of books in a ball-room; my head is always full of something else.

//傳送訊息// 宣告自己不可訪問並關閉複製程式碼通用屬性from/to/type/idfrom的屬性並非由客戶端提供,而是服務端進行的標記。presence節presence提供網路實體的可訪問性。使用者發出presence節,表明自己上線,這樣可以會有更大的概率與別人通訊(人們更願意與線上的人交流),但是我們也不用擔心任何人都可以看到自己的線上狀態,除非我們訂閱了該使用者的狀態,訂閱之後,使用者的狀態資訊會自動傳送到訂閱者處。實際上,XMPP的presence節是一個簡單的專用的釋出-訂閱方法。在IM中,presence體現在花名冊(roster)中,花名冊儲存有JID列表以及使用者與這些JID的訂閱關係,一旦上線,使用者傳送presence節,剩下的就由伺服器處理了(通知自己線上,以及獲取聯絡人的狀態資訊)message節用於從一個實體向另外一個實體傳送訊息,並可以傳輸任何型別的結構化資訊,不保證傳輸可靠性message是一個非常基礎的推模型,message通常用於IM,groupchat,警告和通知等。message的type有如下幾種:normal    類似於email,發出後不等待迴應chat    用於兩個實體間的實時通訊groupchat    多使用者聊天室中使用headline    用於傳送警告或通知error傳送錯誤資訊Who are you?Query除了type之外,典型的message節中還包含from、to或者id屬性(用於目的追蹤)。to中的JID為訊息的接受者,from是傳送者的JID,但是from屬性並非由客戶端提供,而是傳送者的服務端提供的,以避免地址模仿。message節中也可以包含未在XMPP協議中定義的負載,可以用於擴充套件。IQ節表示Info/Query,為XMPP通訊提供請求及響應機制,類似於GET/POST/PUT方法。IQ只能包含一個payload,並且定義了需要由伺服器處理的請求或者動作。相對於message來說,IQ具有更好的可靠性,因其要求收到迴應。IQ中包含有id屬性,用於識別伺服器發回的響應。get    用於請求資訊,類似於HTTP Getset    提供資訊或請求,類似於HTTP POST/PUTresult    響應請求,類似於HTTP 200error    錯誤資訊例子傳送獲取花名冊請求伺服器返回花名冊複製程式碼複製程式碼使用者新增一個聯絡人伺服器響應error節具有明確的結構,通常包含原節內容,通用錯誤資訊以及應用程式特有的錯誤條件和資訊(可選)可擴充套件XMPP協議是基於XML的協議,因此其天生提供了很好的可擴充套件性。我們可以用XMPP傳遞各種資訊,包括連結、位置資訊,Web Service等。連線生命週期傳送XMPP節通常需要建立一個經過身份驗證的XMPP會話,包括連線、流的建立、身份驗證以及斷開連線。連線在傳送任何節之前,需要建立XMPP流,在XMPP流存在之前,必須建立通往XMPP伺服器的連線。當XMPP客戶端或者伺服器連線到另外一個XMPP伺服器時,首先要查詢SRV記錄,該記錄儲存有特定域的伺服器列表。查詢應答中可以包含多條SRV記錄,這樣就可以在多個伺服器中建立負載均衡連線。如果沒有找到合適的SRV記錄,那麼程式將試圖直接連線到指定域。流的建立  一旦建立通過給定XMPP伺服器的連線,XMPP流就啟動了  向伺服器傳送,就可以開啟XMPP流,伺服器傳送響應流的起始標記進行響應建立XMPP流之後就可以來回傳送各種元素  伺服器傳送元素,列舉XMPP流中支援所有功能,大多數與可用的加密和身份驗證選型有關身份驗證XMPP允許進行TLS(Transport Layer Security,傳輸層安全)加密,而且大多數客戶端預設使用該功能。一旦伺服器通告TLS支援後,客戶端就會啟動TLS連線並將當前套接字升級為加密套接字而不斷開連線。一旦TLS加密確立,就會建立一對新的XMPP流。XMPP中的身份驗證使用SASL(Simple Authentication and Security Layers,簡單身份驗證與安全層)協議並支援多種身份驗證機制(取決於伺服器)。一旦完成身份驗證,客戶端必須為連線繫結一個資源並啟動一個會話,通過和元素髮送。當兩臺伺服器相互連線時,身份驗證步驟稍稍不同。連線斷開當使用者結束XMPP會話後,他們終止會話並斷開連線,最優雅的方式是首先傳送無效出席資訊,然後關閉元素。

相關文章