要學習基于XMPP協(xié)議的IM開發(fā),首先要熟悉XMPP協(xié)議本身。
XMPP協(xié)議的組成
主要的XMPP 協(xié)議范本及當今應用很廣的XMPP 擴展:
RFC 3920 XMPP:核心。定義了XMPP 協(xié)議框架下應用的網(wǎng)絡架構,引入了XML Stream(XML 流)與XML Stanza(XML 節(jié)),并規(guī)定XMPP 協(xié)議在通信過程中使用的XML 標簽。使用XML 標簽從根本上說是協(xié)議開放性與擴展性的需要。此外,在通信的安全方面,把TLS 安全傳輸機制與SASL 認證機制引入到內(nèi)核,與XMPP 進行無縫的連接,為協(xié)議的安全性、可靠性奠定了基礎。Core 文檔還規(guī)定了錯誤的定義及處理、XML 的使用規(guī)范、JID(Jabber Identifier,Jabber 標識符)的定義、命名規(guī)范等等。所以這是所有基于XMPP 協(xié)議的應用都必需支持的文檔。
RFC 3921:用戶成功登陸到服務器之后,發(fā)布更新自己的在線好友管理、發(fā)送即時聊天消息等業(yè)務。所有的這些業(yè)務都是通過三種基本的XML 節(jié)來完成的:IQ Stanza(IQ 節(jié)), Presence Stanza(Presence 節(jié)), Message Stanza(Message 節(jié))。RFC3921 還對阻塞策略進行了定義,定義是多種阻塞方式??梢哉f,RFC3921 是RFC3920 的充分補充。兩個文檔結合起來,就形成了一個基本的即時通信協(xié)議平臺,在這個平臺上可以開發(fā)出各種各樣的應用。
XEP-0030 服務搜索。一個強大的用來測定XMPP 網(wǎng)絡中的其它實體所支持特性的協(xié)議。
XEP-0115 實體性能。XEP-0030 的一個通過即時出席的定制,可以實時改變交變廣告功能。
XEP-0045 多人聊天。一組定義參與和管理多用戶聊天室的協(xié)議,類似于Internet 的Relay Chat,具有很高的安全性。
XEP-0096 文件傳輸。定義了從一個XMPP 實體到另一個的文件傳輸。
XEP-0124 HTTP 綁定。將XMPP 綁定到HTTP 而不是TCP,主要用于不能夠持久的維持與服務器TCP 連接的設備。
XEP-0166 Jingle。規(guī)定了多媒體通信協(xié)商的整體架構。
XEP-0167 Jingle Audio Content Description Format。定義了從一個XMPP 實體到另一個的語音傳輸過程。
XEP-0176 Jingle ICE(Interactive Connectivity Establishment)Transport。ICE傳輸機制,文件解決了如何讓防火墻或是NAT(Network Address Translation)保護下的實體建立連接的問題。
XEP-0177 Jingle Raw UDP Transport。純UDP 傳輸機制,文件講述了如何在沒有防火墻且在同一網(wǎng)絡下建立連接的。
XEP-0180 Jingle Video Content Description Format。定義了從一個XMPP 實體到另一個的視頻傳輸過程。
XEP-0181 Jingle DTMF(Dual Tone Multi-Frequency)。
XEP-0183 Jingle Telepathy Transport Method。
XMPP協(xié)議網(wǎng)絡架構
XMPP是一個典型的C/S架構,而不是像大多數(shù)即時通訊軟件一樣,使用P2P客戶端到客戶端的架構,也就是說在大多數(shù)情況下,當兩個客戶端進行通訊時,他們的消息都是通過服務器傳遞的(也有例外,例如在兩個客戶端傳輸文件時).采用這種架構,主要是為了簡化客戶端,將大多數(shù)工作放在服務器端進行,這樣,客戶端的工作就比較簡單,而且,當增加功能時,多數(shù)是在服務器端進行.XMPP服務的框架結構如下圖所示.XMPP中定義了三個角色,XMPP客戶端,XMPP服務器、網(wǎng)關.通信能夠在這三者的任意兩個之間雙向發(fā)生.服務器同時承擔了客戶端信息記錄、連接管理和信息的路由功能.網(wǎng)關承擔著與異構即時通信系統(tǒng)的互聯(lián)互通,異構系統(tǒng)可以包括SMS(短信)、MSN、ICQ等.基本的網(wǎng)絡形式是單客戶端通過TCP/IP連接到單服務器,然后在之上傳輸XML,工作原理是:
(1)節(jié)點連接到服務器;(2)服務器利用本地目錄系統(tǒng)中的證書對其認證;(3)節(jié)點指定目標地址,讓服務器告知目標狀態(tài);(4)服務器查找、連接并進行相互認證;(5)節(jié)點之間進行交互.
XMPP客戶端
XMPP 系統(tǒng)的一個設計標準是必須支持簡單的客戶端。事實上,XMPP 系統(tǒng)架構對客戶端只有很少的幾個限制。一個XMPP 客戶端必須支持的功能有:
通過 TCP 套接字與XMPP 服務器進行通信;
解析組織好的 XML 信息包;
理解消息數(shù)據(jù)類型。
XMPP 將復雜性從客戶端轉(zhuǎn)移到服務器端。這使得客戶端編寫變得非常容易,更新系統(tǒng)功能也同樣變得容易。XMPP 客戶端與服務端通過XML 在TCP 套接字的5222 端口進行通信,而不需要客戶端之間直接進行通信。
基本的XMPP 客戶端必須實現(xiàn)以下標準協(xié)議(XEP-0211):
RFC3920 核心協(xié)議Core
RFC3921 即時消息和出席協(xié)議Instant Messaging and Presence
XEP-0030 服務發(fā)現(xiàn)Service Discovery
XEP-0115 實體能力Entity Capabilities
XMPP服務器
XMPP 服務器遵循兩個主要法則:
l 監(jiān)聽客戶端連接,并直接與客戶端應用程序通信;
l 與其他 XMPP 服務器通信;
XMPP開源服務器一般被設計成模塊化,由各個不同的代碼包構成,這些代碼包分別處理Session管理、用戶和服務器之間的通信、服務器之間的通信、DNS(Domain Name System)轉(zhuǎn)換、存儲用戶的個人信息和朋友名單、保留用戶在下線時收到的信息、用戶注冊、用戶的身份和權限認證、根據(jù)用戶的要求過濾信息和系統(tǒng)記錄等。另外,服務器可以通過附加服務來進行擴展,如完整的安全策略,允許服務器組件的連接或客戶端選擇,通向其他消息系統(tǒng)的網(wǎng)關。
基本的XMPP 服務器必須實現(xiàn)以下標準協(xié)議
RFC3920 核心協(xié)議Core
RFC3921 即時消息和出席協(xié)議Instant Messaging and Presence
XEP-0030 服務發(fā)現(xiàn)Service Discovery
XMPP網(wǎng)關
XMPP 突出的特點是可以和其他即時通信系統(tǒng)交換信息和用戶在線狀況。由于協(xié)議不同,XMPP 和其他系統(tǒng)交換信息必須通過協(xié)議的轉(zhuǎn)換來實現(xiàn),目前幾種主流即時通信協(xié)議都沒有公開,所以XMPP 服務器本身并沒有實現(xiàn)和其他協(xié)議的轉(zhuǎn)換,但它的架構允許轉(zhuǎn)換的實現(xiàn)。實現(xiàn)這個特殊功能的服務端在XMPP 架構里叫做網(wǎng)關(gateway)。目前,XMPP 實現(xiàn)了和AIM、ICQ、IRC、MSN Massager、RSS0.9 和Yahoo Massager 的協(xié)議轉(zhuǎn)換。由于網(wǎng)關的存在,XMPP 架構事實上兼容所有其他即時通信網(wǎng)絡,這無疑大大提高了XMPP 的靈活性和可擴展性。
XMPP地址格式
一個實體在XMPP網(wǎng)絡結構中被稱為一個接點,它有唯一的標示符jabber identifier(JID),即實體地址,用來表示一個Jabber用戶,但是也可以表示其他內(nèi)容,例如一個聊天室.一個有效的JID包括一系列元素:(1)域名(domain identifier);(2)節(jié)點(node identifier);(3)源(resource identifier).它的格式是node@domain/resource,node@domain,類似電子郵件的地址格式.domain用來表示接點不同的設備或位置,這個是可選的,例如a在Server1上注冊了一個用戶,用戶名為doom,那么a的JID就是doom@serverl,在發(fā)送消息時,指明doom@serverl就可以了,resource可以不用指定,但a在登錄到這個Server時,fl的JID可能是doom@serverl、exodus(如果a用Exodus軟件登錄),也可能是doom@serverl/psi(如果a用psi軟件登錄).資源只用來識別屬于用戶的位置或設備等,一個用戶可以同時以多種資源與同一個XMPP服務器連接。
XMPP消息格式
XMPP中定義了3個頂層XML元素: Message、Presence、IQ,下面針對這三種元素進行介紹。
用于在兩個jabber用戶之間發(fā)送信息。Jsm(jabber會話管理器)負責滿足所有的消息,不管目標用戶的狀態(tài)如何。如果用戶在線jsm立即提交;否則jsm就存儲。
To :標識消息的接收方。
from : 指發(fā)送方的名字或標示(id)o
Text: 此元素包含了要提交給目標用戶的信息。
結構如下所示:
<message to= ‘lily@jabber.org/contact' type =’chat'>
你好,在忙嗎
用來表明用戶的狀態(tài),如:online、away、dnd(請勿打擾)等。當用戶離線或改變自己的狀態(tài)時,就會在stream的上下文中插入一個Presence元素,來表明自身的狀態(tài).結構如下所示:
From =‘lily @ jabber.com/contact’
To = ‘yaoman @ jabber.com/contact'
Online
元素可以取下面幾種值:
Probe :用于向接受消息方法發(fā)送特殊的請求
subscribe:當接受方狀態(tài)改變時,自動向發(fā)送方發(fā)送presence信息。
< IQ >
一種請求/響應機制,從一個實體從發(fā)送請求,另外一個實體接受請求,并進行響應.例如,client在stream的上下文中插入一個元素,向Server請求得到自己的好友列表,Server返回一個,里面是請求的結果.
主要的屬性是type。包括:
Get :獲取當前域值。
Set :設置或替換get查詢的值。
Result :說明成功的響應了先前的查詢。
Error: 查詢和響應中出現(xiàn)的錯誤。
結構如下所示:
<iq from =‘lily @ jabber.com/contact’id=’1364564666’ Type=’result’>
另外協(xié)議中還有一些概念需要重復一下,便于理解!
什么是stanza(節(jié))?
消息節(jié)點(類似于xml中的節(jié)點元素),可以理解為各種各樣的消息節(jié)點(plugin可以對這些自定義消息進行針對性識別和處理).
RFC 3920 XMPP:核心。定義了XMPP 協(xié)議框架下應用的網(wǎng)絡架構,引入了XML Stream(XML 流)與XML Stanza(XML 節(jié)),并規(guī)定XMPP 協(xié)議在通信過程中使用的XML 標簽。使用XML 標簽從根本上說是協(xié)議開放性與擴展性的需要。此外,在通信的安全方面,把TLS 安全傳輸機制與SASL 認證機制引入到內(nèi)核,與XMPP 進行無縫的連接,為協(xié)議的安全性、可靠性奠定了基礎。Core 文檔還規(guī)定了錯誤的定義及處理、XML 的使用規(guī)范、JID(Jabber Identifier,Jabber 標識符)的定義、命名規(guī)范等等。所以這是所有基于XMPP 協(xié)議的應用都必需支持的文檔。
RFC 3921:用戶成功登陸到服務器之后,發(fā)布更新自己的在線好友管理、發(fā)送即時聊天消息等業(yè)務。所有的這些業(yè)務都是通過三種基本的XML 節(jié)來完成的:IQ Stanza(IQ 節(jié)), Presence Stanza(Presence 節(jié)), Message Stanza(Message 節(jié))。RFC3921 還對阻塞策略進行了定義,定義是多種阻塞方式。可以說,RFC3921 是RFC3920 的充分補充。兩個文檔結合起來,就形成了一個基本的即時通信協(xié)議平臺,在這個平臺上可以開發(fā)出各種各樣的應用。
什么是JID?
XMPP的地址叫做JabberID(簡寫為JID),它用來標示XMPP網(wǎng)絡中的各個XMPP實體。JID由三部分組成:domain,node identifier和resource。JID中domain是必不可少的部分。注意:domain和user部分是不分大小寫的,但是resource區(qū)分大小寫。
jid = [ node "@" ] domain [ "/" resource ]
domain = fqdn / address-literal
fqdn = (sub-domain 1*("." sub-domain))
sub-domain = (internationalized domain label)
address-literal = IPv4address / IPv6address
domain:通常指網(wǎng)絡中的網(wǎng)關或者服務器。 node identifier:通常表示一個向服務器或網(wǎng)關請求和使用網(wǎng)絡服務的實體(比如一個客戶端),當然它也能夠表示其他的實體(比如在多用戶聊天系統(tǒng)中的一個房間)。 resource:通常表示一個特定的會話(與某個設備),連接(與某個地址),或者一個附屬于某個節(jié)點ID實體相關實體的對象(比如多用戶聊天室中的一個參加者)。
JID種類有:
bare JID:user@domain.tld
full JID:user@domain.tld/resource
例子:
stpeter@jabber.org:表示服務器jabber.org上的用戶stpeter。 room@service:一個用來提供多用戶聊天服務的特定的聊天室。這里 “room“ 是聊天室的名字, ”service“ 是多用戶聊天服務的主機名。 room@service/nick:加入了聊天室的用戶nick的地址。這里 “room“ 是聊天室的名字, ”service“ 是多用戶聊天服務的主機名,”nick“ 是用戶在聊天室的昵稱。
為了標示JID,XMPP也有自己的URI,例如xmpp:stpeter@jabber.org,默認規(guī)則是在JID前加 xmpp:。
一個基本的IM具備以下功能
1、用戶系統(tǒng):用戶注冊、登錄、添加好友、刪除好友、好友列表、支持上傳頭像、可以修改個人信息、名稱、性別、地區(qū)、簽名、黑名單功能、拉入黑名單將無法收到對方的信息、查看好友當前地理位置。
2、聊天系統(tǒng):發(fā)送文字、圖片、語音、表情。語音聊天可以顯示時長、未讀狀態(tài),自動輪播未讀語音;
3、群聊系統(tǒng):建立房間、加入房間、刪除房間、房間列表、群聊、屏蔽群消息功能、邀請、踢出好友(只有房主才有這個功能)。并有操作日志實時顯示在房間中
4、附近人功能:根據(jù)篩選條件查看附近的人,查看用戶時能顯示位置
5、朋友圈:支持發(fā)送文本、圖片、語音、視頻或以上混合消息,支持好友進行贊、評論、轉(zhuǎn)發(fā)、送禮物等操作,并且可以根據(jù)消息顯示粉絲貢獻值。