Jabber即時(shí)通信系統(tǒng)服務(wù)整體框架的概述
本文檔包括以下內(nèi)容:
Introduction 簡(jiǎn)介
Foundations 基本知識(shí)
High-Level Server Architecture高階服務(wù)體系
Basic Message Flow基本信息流程
Authentication 鑒定
Jabber Session Manager Jabber會(huì)話管理
Threading 線程
Deliver Logic發(fā)送邏輯
Transport 傳送器
Subscriptions 訂閱
Jabber IDs
Server Dialback 服務(wù)
Conclusion 結(jié)束語
Copyright Information 版權(quán)信息
第一個(gè)Jabber技術(shù)的應(yīng)用是由開源社區(qū)發(fā)起并一直領(lǐng)導(dǎo)的即時(shí)消息的實(shí)時(shí)系統(tǒng)。Jabber即時(shí)消息(IM)系統(tǒng)和現(xiàn)有IM服務(wù)相比較由以下幾個(gè)關(guān)鍵特點(diǎn):
XML為基礎(chǔ)
分布式網(wǎng)絡(luò)
開放的協(xié)議和內(nèi)核代碼
模塊化的、可擴(kuò)展的系統(tǒng)架構(gòu)
本文檔提供一個(gè)關(guān)于Jabber系統(tǒng)架構(gòu)的高階概述,主要集中介紹Jabber開源服務(wù)器的設(shè)計(jì),目前的版本是1.4(譯注:目前最新版本是2.0)。關(guān)于Jabber的XML協(xié)議的相關(guān)內(nèi)容,請(qǐng)參見Jabber Protocol Overview參考文檔(http://docs.jabber.org/general/html/protocol.html)。
(注:本文檔綜合了以下文件內(nèi)容:Jeremie Miller
Jabber在設(shè)計(jì)上很大程度上沿襲了Internet上最成功的消息系統(tǒng):即email。這樣Jabber就可以在一個(gè)使用共同協(xié)議的服務(wù)器組成的分布式網(wǎng)絡(luò)上提供通信,連接這個(gè)網(wǎng)絡(luò)的客戶端,可以象接收消息一樣發(fā)送消息給同一個(gè)服務(wù)器或其他Internet上的服務(wù)器上的用戶。不過,盡管email是一個(gè)存儲(chǔ)-轉(zhuǎn)發(fā)系統(tǒng),但Jabber轉(zhuǎn)發(fā)消息卻是實(shí)時(shí)的,因?yàn)?/span>Jabber服務(wù)器(連同其他所有Jabber服務(wù)器在內(nèi))知道一個(gè)用戶什么時(shí)候在線。這個(gè)能力被成為在線,也是即時(shí)消息的核心所在。Jabber通過兩個(gè)附加功能提供這些IM標(biāo)準(zhǔn)特性,這也使得Jabber與眾不同。首先是一個(gè)允許消息系統(tǒng)間協(xié)同作業(yè)的開放協(xié)議。其次是建立在XML上的強(qiáng)大根本,它使得非但是兩個(gè)人之間的通信,甚至是應(yīng)用軟件之間的通信成為了可能。
上述每一個(gè)功能都將在下文進(jìn)行進(jìn)一步的闡述,并進(jìn)一步擴(kuò)展本文檔的內(nèi)容。
Jabber使用的是客戶端-服務(wù)端的系統(tǒng)架構(gòu),而不是其它一些即時(shí)消息系統(tǒng)使用的客戶端-客戶端的系統(tǒng)架構(gòu)。所有從一個(gè)客戶端發(fā)給另一個(gè)客戶端的Jabber消息和數(shù)據(jù)都必須通過服務(wù)端。任何一個(gè)客戶端都可以通過商議與另一個(gè)客戶端自由地建立一個(gè)直接地連接,但這些連接只用于特殊服務(wù)地應(yīng)用。有一些實(shí)例被鼓勵(lì)建立這種連接,比如文件傳輸,但這些實(shí)例必須先通過一個(gè)客戶端-服務(wù)端形勢(shì)進(jìn)行協(xié)商,才能建立。
Jabber地網(wǎng)絡(luò)體系是模仿e-mail系統(tǒng)地。每一個(gè)用戶都有自己的本地服務(wù)器,并從該服務(wù)器上接收信息,消息和在線信息在這些服務(wù)器之間傳輸??梢蕴砑尤我鈹?shù)目的Jabber服務(wù)器,這些服務(wù)器接受客戶端的連接,并與其它Jabber服務(wù)器進(jìn)行通信。每一個(gè)Jabber服務(wù)器都獨(dú)立于其他Jabber服務(wù)器,并且擁有其自身的用戶列表。通過Internet,任一Jabber服務(wù)器都可以與其他Jabber服務(wù)器進(jìn)行通話。每一個(gè)用戶都與一個(gè)特殊服務(wù)器(提供注冊(cè)服務(wù)的服務(wù)提供商或行政管理企業(yè))相對(duì)應(yīng),Jabber地址和email地址的形勢(shì)是一樣的,如:stpeter@jabber.org(下面的Jabber ID部分將介紹更多關(guān)于Jabber地址的信息)。
Jabber服務(wù)器遵循兩個(gè)主要法則:
監(jiān)聽客戶端連接,并直接與客戶端應(yīng)用程序通信
與其他Jabber服務(wù)器通信
Jabber開源服務(wù)器被設(shè)計(jì)成模塊化,由各個(gè)不同的代碼包構(gòu)成,這些代碼包分別處理類似用戶認(rèn)證、數(shù)據(jù)存儲(chǔ)(離線消息,花名冊(cè),用戶信息等)等等。另外,服務(wù)器可以通過附加服務(wù)來進(jìn)行擴(kuò)展,如完整的安全策略,允許服務(wù)器組件的連接或客戶端選擇,通向其他消息系統(tǒng)的網(wǎng)關(guān)。
一個(gè)模塊化的例子就是通過Jabber XML翻譯成其他協(xié)議的獨(dú)立“transport”(傳輸器),可以實(shí)現(xiàn)Jabber消息系統(tǒng)與非Jabber消息系統(tǒng)之間進(jìn)行消息和在線信息的交流。這些傳輸器并不是服務(wù)器內(nèi)核。相反,它們是很容易添加到服務(wù)器內(nèi)核服務(wù)器端程序,為終端用戶提供更強(qiáng)大的功能服務(wù)。
Jabber系統(tǒng)的一個(gè)設(shè)計(jì)標(biāo)準(zhǔn)是必須支持簡(jiǎn)單的客戶端(如同和telnet連接一樣簡(jiǎn)單的客戶端)。事實(shí)上,Jabber系統(tǒng)架構(gòu)對(duì)客戶端只有很少的幾個(gè)限制。一個(gè)Jabber客戶端必須支持的功能有:
通過TCP 套接字與Jabber服務(wù)器進(jìn)行通信
解析組織好的XML信息包
理解消息數(shù)據(jù)類型
Jabber將復(fù)雜性從客戶端轉(zhuǎn)移到服務(wù)器端。這使得客戶端編寫變得非常容易(一個(gè)證據(jù)就是今天出現(xiàn)了種類繁多的客戶端),更新系統(tǒng)功能也同樣變得容易(這樣,就不用強(qiáng)迫用戶去下載新的客戶端)。Jabber客戶端與服務(wù)端通過XML在TCP 套接字的5222以上端口進(jìn)行通信,而不需要客戶端之間直接進(jìn)行通信。在實(shí)際應(yīng)用中,許多低階的客戶端功能(如解析XML,理解基本的jabber XML語言類似<message/>,<presence/>,<iq/>)已經(jīng)包含在Jabber客戶端類庫(kù)中,這樣可以讓客戶端的開發(fā)人員更多的注重用戶界面的開發(fā)。
XML是Jabber系統(tǒng)架構(gòu)的核心部分,它最重要的作用是系統(tǒng)的底層可擴(kuò)展性,并能表述幾乎任何一種結(jié)構(gòu)化數(shù)據(jù)。(特別地,Jabber利用XML數(shù)據(jù)流進(jìn)行客戶端-服務(wù)器端以及服務(wù)器端-服務(wù)器端的通信。XML數(shù)據(jù)流一般是由客戶端發(fā)起至服務(wù)端,XML數(shù)據(jù)流的有效時(shí)間直接與用戶的在線會(huì)話有效時(shí)間相關(guān)聯(lián)。)
Jabber嚴(yán)格遵守XML的同時(shí),不需要知道任何關(guān)于信息轉(zhuǎn)發(fā)中介的信息:對(duì)于信息轉(zhuǎn)發(fā)中介沒有任何固有的規(guī)定,也不需要任何關(guān)于信息轉(zhuǎn)發(fā)中介的系統(tǒng)架構(gòu)的知識(shí)。這都是可能的,在另一方面,這也使得提供與第三方服務(wù)(如:IRC,ICQ,AIM)進(jìn)行信息傳輸?shù)膫鬏斊鞯膶?shí)現(xiàn)成為可能。而在Jabber系統(tǒng)內(nèi)部,就像Jabber系統(tǒng)中其它每一個(gè)組件一樣,傳輸器使用XML語音。更多關(guān)于Jabber XML協(xié)議的信息可以在《Jabber協(xié)議概述》(http://docs.jabber.org/general/html/protocol.html)中。
Jabber服務(wù)器由若干個(gè)組件構(gòu)成,這些組件分別完成Jabber系統(tǒng)中邏輯上獨(dú)立的各個(gè)功能。服務(wù)器的內(nèi)核是一個(gè)轉(zhuǎn)發(fā)組件,這個(gè)組件的唯一功能就是從一個(gè)基本組件往另一個(gè)基本組件進(jìn)行XML解析傳遞。共有四個(gè)這樣的基本組件:接收、連接、執(zhí)行、裝入。這些基本組件解析傳入的XML,轉(zhuǎn)發(fā)給其他基本組件,并使得基本組件的下游組件能夠連續(xù)的使用XML。下面是一個(gè)高階的系統(tǒng)架構(gòu)的演示圖:
一個(gè)服務(wù)器啟動(dòng)后,Jabber服務(wù)器負(fù)責(zé)注冊(cè)的組件通過Jabber的主程序后臺(tái)(如同在服務(wù)器的配置文件中定義的一樣)執(zhí)行其功能單元(?),并運(yùn)行由這些功能單元組成的信息包(以此來定義所有信息包的傳送邏輯)。Jabber服務(wù)器的內(nèi)核包括處理以下公共任務(wù)的組件:
會(huì)話管理
客戶端-服務(wù)端的通信
服務(wù)器-服務(wù)器的通信
DNS解決方案
用戶認(rèn)證
用戶注冊(cè)
數(shù)據(jù)庫(kù)查詢
為離線用戶存儲(chǔ)信息
存儲(chǔ)并找回vCards
根據(jù)用戶設(shè)定過濾信息
群組聊天(多對(duì)多的通信)
系統(tǒng)日志
另外,服務(wù)器內(nèi)核能夠補(bǔ)充“傳輸器”,這些“傳輸器”被設(shè)計(jì)來解決不同于Jabber開放的XML格式的其他協(xié)議。(詳情見傳輸器部分)。這些傳輸器可以很自然地作為整體服務(wù)器系統(tǒng)架構(gòu)的內(nèi)置組件存在。目前存在進(jìn)行翻譯功能的傳輸器主要是針對(duì)以下的協(xié)議:
AOL Instant Messenger(AIM)
ICQ
Internet Relay Chat(IRC)
MSN Messenger
Rich Site Summary(RSS 0.9)
Yahoo! Messenger
(注:附加的傳輸器可以根據(jù)需要增加到Jabber上,例如為了解決IM不統(tǒng)一的格式,但未來的傳輸器沒有在本文檔中闡述。)
對(duì)于學(xué)習(xí)Jabber系統(tǒng)而言,研究通過服務(wù)器的典型數(shù)據(jù)流程是一個(gè)好的入門方式。(當(dāng)XML的“消息”元素僅指Jabber開放的XML協(xié)議中規(guī)定的三種主要元素中的一種時(shí),它更能體現(xiàn)Jabber最核心的意圖:通過使用XML進(jìn)行消息的點(diǎn)對(duì)點(diǎn)發(fā)送。)
下面是關(guān)于該數(shù)據(jù)流程的圖表:
Jabber服務(wù)器(在上述圖表中簡(jiǎn)化為“jabberd”,原義為“Jabber daemon [Jabber后臺(tái)程序]”)在主機(jī)上的用戶會(huì)話的上下文中接收型為“消息”的包體,正常情況下,該包體在5222端口(如果SSL允許并運(yùn)行的情況下也可以是5223端口)通過一個(gè)直接的TCP套接字產(chǎn)生。如果會(huì)話不存在,jabberd將發(fā)起認(rèn)證流程,該流程將會(huì)在下面的認(rèn)真部分中進(jìn)行介紹。如果會(huì)話存在,消息包將被送往Jabber會(huì)話管理組件(簡(jiǎn)稱“JSM”)。
下面是一個(gè)XML的例子:
<message
to=’psaintandre@aim.jabber.org’
type=’chat’>
<body>Hey, the AIM transport is working great!</body>
</message>
接著,JSM根據(jù)Jabber服務(wù)器的內(nèi)部配置文件上的服務(wù)器名單查找目標(biāo)服務(wù)器的主機(jī)名。通常主機(jī)名都會(huì)被定義;比如,aim.jabber.org在Jabber.com服務(wù)器上的配置文件被定義為指向該主機(jī)的AIM傳輸器(該傳輸器可能在一臺(tái)單獨(dú)的機(jī)器上)。如果主機(jī)名沒有在配置文件中被定義,“dnsrv”組件將把這個(gè)主機(jī)名于一個(gè)IP地址和端口進(jìn)行對(duì)應(yīng)。另外,由于該主機(jī)有問題,消息包將會(huì)送到服務(wù)器到服務(wù)器(s2s)組件,在這個(gè)例子中,jabber.org。服務(wù)器到服務(wù)器組件將直接從指定的外部Jabber服務(wù)器(比如jabber.org)或該主機(jī)上一個(gè)傳輸器傳入。在上面的例子中,消息包有意傳遞到aim.jabber.org上的一個(gè)地址,因此,這個(gè)包將被送到jabber.org上的AIM傳輸器,再傳送到一個(gè)AOL Instant Messenger 賬號(hào)(見下面的傳輸器部分)。另一個(gè)方面,最終的結(jié)果是一個(gè)消息從一個(gè)Jabber客戶端流通過一個(gè)Jabber服務(wù)器流動(dòng)到另一個(gè)Jabber服務(wù)器或外部IM系統(tǒng)。
在基本消息流程中提到,消息和在線信息是通過Jabber服務(wù)器上一個(gè)運(yùn)行中的主機(jī)上的一個(gè)用戶會(huì)話的上下文發(fā)送給Jabber的。在Jabber協(xié)議中規(guī)定,這個(gè)會(huì)話由兩個(gè)XML流保持,一個(gè)是從客戶端到服務(wù)器端,另一個(gè)是從服務(wù)器端到客戶端。下面是一個(gè)會(huì)話的XML顯示:
SEND:<stream:stream
SEND:to=’jabber.org’
SEND:xmlns=’jabber:client’
SEND:xmlns:stream=’http://etherx.jabber.org/streams’>
RECV:<stream:stream
RECV:xmls:stream=’http://etherx.jabber.org/streams’
RECV:id=’39ABA7D
RECV:xmlns=’jabber:client’
RECV:from=’jabber.org’>
SEND:<iq id=’
SEND:<query xmlns=’jabber:iq:auth’>
SEND:<username>stpeter</username>
SEND:<resource>Gabber</resource>
SEND:<digest>file881517e9917bb815fed112d811d32b4e4b3aed</digest>
SEND:</query>
SEND:</iq>
RECV:<iq id=’
(XML for user session goes here)
SEND:</stream:stream>
RECV:</stream:stream>
為了讓服務(wù)器建立一個(gè)會(huì)話,首先必須對(duì)用戶進(jìn)行認(rèn)證。下面的圖表展示的就是認(rèn)證的活動(dòng)流程:
當(dāng)客戶端連接到主機(jī),并發(fā)起一個(gè)XML流時(shí),認(rèn)證流程就開始了。Jabber服務(wù)器會(huì)立即在’jabber:iq:auth’的名字空間中對(duì)’iq’(info/query的簡(jiǎn)稱)類型和’query’子類型的包體進(jìn)行查詢,該名字空間含有對(duì)用戶的認(rèn)證信息。認(rèn)證信息必須包含一個(gè)用戶名和明文密碼(很明顯,這是讓人沮喪的),一個(gè)使用SHA1算法(這個(gè)默認(rèn)的認(rèn)證是設(shè)計(jì)為a.k.a的“數(shù)字認(rèn)證”)加密的密碼,或者是一些符合零度認(rèn)證的數(shù)據(jù)。
一旦認(rèn)證信息被接收到,XML解釋器發(fā)送控制命令給Jabber服務(wù)器的“傳送”組件,該組件將把從客戶端未等待認(rèn)證結(jié)果就發(fā)送過來的XML進(jìn)行緩存。主機(jī)(通常,但不全是以JSM形式存在)將把認(rèn)證包傳送到Jabber服務(wù)器的’xdb’組件。xdb組件(’xdb’即“Xml Data Base”――XML基數(shù)據(jù))將把認(rèn)證包發(fā)送給任一注冊(cè)了該認(rèn)證包類型的子組件:例如,明文認(rèn)證包可能通過檢查文件系統(tǒng)中的XML文件用于’xbd_file’子組件,而數(shù)字認(rèn)證包通過檢查LDAP用于’xdb_ldap’子組件。傳送組件不作任何處理將認(rèn)證包傳送給xdb組件,xdb組件將把該認(rèn)證包發(fā)送給合適的子組件。另外,為了提高性能,xdb_ldap組件擁有其獨(dú)立的線程池,其運(yùn)作方式與會(huì)話管理器中的線程模式類似。
Xdb組件將認(rèn)證查詢的結(jié)果返回給主機(jī)(同樣,通常是JSM)。如果認(rèn)證失敗,服務(wù)器將返回錯(cuò)誤代碼401給客戶端而不發(fā)起一個(gè)會(huì)話。如果認(rèn)證成功,JSM將開啟一個(gè)會(huì)話(如果需要的話將釋放XML緩存),所有在線信息,消息,以及iq基本信息在用戶會(huì)話的上下文中進(jìn)行來回傳遞,直到客戶端或服務(wù)端通過發(fā)送一個(gè)關(guān)閉數(shù)據(jù)流的標(biāo)志(</stream>)終止。
下面是Jabber會(huì)話管理器的活動(dòng)流程:
前面提到,Jabber會(huì)話管理器組件(簡(jiǎn)稱JSM)處理各種類型的包:消息類型、在線信息類型、查詢連接到一個(gè)Jabber主機(jī)上的發(fā)起者或送達(dá)者的Jabber用戶信息。同時(shí),JSM也處理針對(duì)離線用戶的數(shù)據(jù)包。比如,盡管我不在線,你還是通過我的Jabber ID(stpeter@jabber.org)發(fā)了一條消息給我。JSM將對(duì)這條消息進(jìn)行適當(dāng)處理,很可能一直保存到我再次上線。
JSM通過從XML流中查找“資源”元素(所謂的“資源”是指設(shè)備、客戶端、我的連接所在的位置;可能是“laptop”、“Gabber”、“home”)來判斷用戶是否在線。通常,如果一個(gè)數(shù)據(jù)包不包含資源元素,表明該用戶不在線。但有時(shí)資源元素會(huì)因?yàn)殄e(cuò)誤而丟失,因此JSM在肯定用戶真的離線后,才發(fā)送消息包給“離線”組件,“離線”組件可能(舉例而言)會(huì)保存該消息或重新找回一個(gè)vCard。
如果用戶在線,消息、在線信息、iq包不再發(fā)送到離線組件,而是由JSM進(jìn)行處理。實(shí)際上,任何一個(gè)包只會(huì)有一到兩個(gè)可能的狀態(tài):要么它被轉(zhuǎn)發(fā)給用戶,要么它由用戶發(fā)出。因此,JSM開啟兩個(gè)監(jiān)聽,一個(gè)是“to”,一個(gè)是“from”,并將它們路由到Jabber服務(wù)器中指定的模塊中。一旦指定模塊處理完包體,包體將被送回監(jiān)聽程序,以備以后更多模塊進(jìn)行處理,如果所有處理完畢,包體將發(fā)送給消息源或消息目的地。
下面這個(gè)例子將有助于理解。我收到從foobar@jabber.org發(fā)出的一個(gè)消息。我在線,因此消息備送達(dá)JSM。“to監(jiān)聽”監(jiān)聽到有一個(gè)包發(fā)給我,于是發(fā)出一個(gè)請(qǐng)求到已經(jīng)注冊(cè)到JSM的模塊。第一個(gè)響應(yīng)模塊是mod_filter,該模塊按用戶指定的標(biāo)準(zhǔn)對(duì)進(jìn)來的消息進(jìn)行排序。在這個(gè)例子中(我好像從來沒有從我們的朋友foobar那里很重要的批評(píng)信息),我配置mod_filter將所有從foobar@jabber.org發(fā)送到我的郵箱的消息通過SMTP傳輸器轉(zhuǎn)寄。我們說mod_filter對(duì)消息進(jìn)行了重新格式化,使得指定接收端現(xiàn)在由smtp.jabber.org取代原來的jabber.org,然后將包體發(fā)回給“to監(jiān)聽者”。另一個(gè)對(duì)已注冊(cè)組件的呼叫上來,單沒有任何回應(yīng),因此包體被送到stpeter@smtp.jabber.org,使得包體直接轉(zhuǎn)寄到我的電子郵箱中。
需要著重指出的是這個(gè)過程是重復(fù)的,所以許多模塊都可以在包體完成發(fā)送到或來自用戶動(dòng)作之前對(duì)包體進(jìn)行處理。這使得JSM擁有了極大的彈性和擴(kuò)展性,因?yàn)檫@樣可以在不對(duì)JSM原有模塊進(jìn)行任何改動(dòng)的基礎(chǔ)上,很容易地添加新地模塊(只需要對(duì)服務(wù)器地配置文件進(jìn)行相應(yīng)修改即可)。
Jabber會(huì)話管理器通過線程來提高性能。當(dāng)服務(wù)啟動(dòng)時(shí),一定數(shù)量地線程被指派到線程池(實(shí)際數(shù)目由配置文件決定)。當(dāng)系統(tǒng)其他部分的裝載組件反饋消息包給會(huì)話管理器時(shí),會(huì)話管理器動(dòng)態(tài)地從線程池中取出沒有使用的線程,將它們指派給消息端口,這些消息端口正排隊(duì)等候包體(一個(gè)“消息端口”表示支持一個(gè)客戶連接的數(shù)據(jù)結(jié)構(gòu))。如果線程池中沒有可用的線程,會(huì)話管理器可能(但不是必須)創(chuàng)建一個(gè)新的線程,并將它指派給指定的消息端口。下面是這個(gè)過程的可視化描述:
傳送組件是服務(wù)器的核心,因?yàn)樗鼘?shù)據(jù)從一個(gè)基本組件移動(dòng)動(dòng)另一個(gè)基本組件。這個(gè)級(jí)別的數(shù)據(jù)處理邏輯如下圖:
一旦一個(gè)包體被傳送到一個(gè)基本組件(接收、連接、執(zhí)行、裝入),它將被發(fā)送到一個(gè)子組件,類似jpolld或xdb_ldap進(jìn)行進(jìn)一步處理。
一個(gè)預(yù)處理的例子可能是一個(gè)xdb(比如一個(gè)數(shù)據(jù)庫(kù)連接)需要被處理。一個(gè)處理?xiàng)l件可以是JSM中所有有用的路由名字空間的總和。一個(gè)傳送包體改變的例子可以是消息格式的改變,比如加上傳入地址。
雖然一個(gè)健壯的、XML基礎(chǔ)的消息系統(tǒng)結(jié)構(gòu)是Jabber項(xiàng)目的核心目標(biāo),另一個(gè)重要的目標(biāo)是進(jìn)行消息系統(tǒng)間的協(xié)同作業(yè)。幸運(yùn)的是,Jabber項(xiàng)目通過使它的協(xié)議完全開放來實(shí)現(xiàn)協(xié)同作業(yè)。同時(shí),Jabber項(xiàng)目通過使用Jabber世界里叫做“傳輸器”的東東來實(shí)現(xiàn)Jabber開放的XML格式與眾多非Jabber格式間的通信。
當(dāng)一個(gè)Jabber用戶發(fā)送消息給一個(gè)外部(非Jabber)系統(tǒng)的用戶時(shí),消息的傳送包括了一個(gè)傳輸器組件的工作。用戶的Jabber客戶端發(fā)送一個(gè)消息給Jabber服務(wù)器,并指明一個(gè)包含外部系統(tǒng)名的Jabber ID(如psaintandre@aim.jabber.org),而不是發(fā)送給外部IM系統(tǒng)上的一個(gè)用戶。接著Jabber服務(wù)器將數(shù)據(jù)指向指定的傳輸器應(yīng)用程序。如果傳輸器是本地的(在同一臺(tái)機(jī)器上運(yùn)行),Jabber服務(wù)器直接與它進(jìn)行通信。如果傳輸器不在本地運(yùn)行(在另一臺(tái)機(jī)器上),本地服務(wù)器發(fā)送一個(gè)包給遠(yuǎn)程服務(wù)器,該遠(yuǎn)程服務(wù)器將會(huì)把包發(fā)送給指定的傳輸器。一旦傳輸器接收到XML包體,它把信息(或指示)“轉(zhuǎn)變”成另一個(gè)IM網(wǎng)絡(luò)可以識(shí)別的本地包,并把這個(gè)本地包傳送到那個(gè)IM網(wǎng)絡(luò)中。
下面是Jabber傳輸器工作的高級(jí)概覽:
實(shí)際上,一個(gè)傳輸器實(shí)現(xiàn)了一個(gè)代理模式。大多數(shù)傳輸器擁有自己的小型會(huì)話管理器,這個(gè)會(huì)話管理器將在線信息、消息、(有時(shí))查詢信息進(jìn)行Jabber XML協(xié)議和“外部的”(非Jabber)協(xié)議之間的轉(zhuǎn)換??偟膩碚f,當(dāng)一個(gè)用戶登陸到Jabber上,傳輸器就為和這個(gè)用戶進(jìn)行通信創(chuàng)建一個(gè)線程。
有時(shí),進(jìn)行Jabber協(xié)議的轉(zhuǎn)換是很直接的,例如,當(dāng)一個(gè)外部協(xié)議是很好的文檔化的(比如IRC協(xié)議,即AIM協(xié)議的“奧斯卡”版本)。而另外有些時(shí)候,對(duì)于封閉的或文檔的自然協(xié)議(如Yahoo! Messenger協(xié)議)進(jìn)行協(xié)議轉(zhuǎn)換就非常困難。人們希望IM統(tǒng)一化組織((http://www.imunified.org (http://www.imunified.org/)))能夠成功開放一些現(xiàn)在還是封閉的消息協(xié)議,或者至少為這些封閉協(xié)議的協(xié)議轉(zhuǎn)換創(chuàng)立一套開放的協(xié)議。
絕大多數(shù)傳輸器都是為了與非Jabber服務(wù)進(jìn)行通信,但也有個(gè)別例外。比如,群組聊天傳輸器,這個(gè)傳輸器使得Jabber用戶們可以在一個(gè)聊天室里進(jìn)行聊天,或者以類似IRC界面的方式進(jìn)行通信。群組傳輸器保留每一個(gè)房間當(dāng)前所有用戶的記錄,并發(fā)送每條消息給該房間的所有用戶,使得一個(gè)房間表現(xiàn)得象一個(gè)映射服務(wù)器。它根據(jù)需要?jiǎng)?chuàng)建和銷毀房間,如果我象加入一個(gè)不存在得房間,傳輸器將創(chuàng)建該房間,如果我使最后一個(gè)離開房間的用戶,傳輸器將在我離開后銷毀這個(gè)房間。每一個(gè)單一的房間通過類似groupname@groupchatserver這樣的名字進(jìn)行識(shí)別,每一個(gè)參與者通過一個(gè)對(duì)其昵稱的唯一描述進(jìn)行識(shí)別。比如,在莎士比亞的《麥克白》中女巫們的“groupchat”可能發(fā)生在一個(gè)地址為cauldron@conference.withces.org的房間,女巫們通過類似cauldron@conference.withces.org/firstwitch的名字進(jìn)行識(shí)別。下面使一個(gè)用戶可能看到的:
一個(gè)Jabber實(shí)體可以訂閱其他Jabber實(shí)體(如:任何和一個(gè)Jabber ID關(guān)聯(lián)的事物)的在線信息,一個(gè)訂閱本質(zhì)上是被訂閱者同意發(fā)送在線狀態(tài)改變給訂閱者。這個(gè)信息同時(shí)存儲(chǔ)在訂閱者和被訂閱者的名單中。當(dāng)我通過認(rèn)證并在服務(wù)器上創(chuàng)建一個(gè)會(huì)話,我的在線信息被存放到Jabber會(huì)話管理器中。當(dāng)我改變我的在線狀態(tài)時(shí),<presence/>包將被服務(wù)器處理,服務(wù)器在我的名單中進(jìn)行查詢,并將在線信息狀態(tài)包發(fā)送給所有訂閱我的在線狀態(tài)的Jabber實(shí)體。訂閱包括一下幾種類別,這些類別存放在包含實(shí)體的名單上:
to――另一個(gè)發(fā)送在線狀態(tài)信息給你的實(shí)體
from――另一個(gè)從你這里獲得在線狀態(tài)信息的實(shí)體
both――另一個(gè)發(fā)送再現(xiàn)信息狀態(tài)給你,又從你這里獲取在線信息狀態(tài)的實(shí)體
none――即不從你這里獲取再現(xiàn)信息狀態(tài),又不發(fā)送在線信息狀態(tài)給你的實(shí)體
發(fā)送在線狀態(tài)信息的實(shí)體并不一定是另一個(gè)Jabber用戶,它也可以是一個(gè)外部的服務(wù),比如一個(gè)數(shù)據(jù)流或一個(gè)非Jabber的IM系統(tǒng)。在后面的例子中,非Jabber系統(tǒng)的用戶訂閱通過一個(gè)傳輸器解決,Jabber用戶注冊(cè)到指定傳輸器(如:icq.jabber.org),以便將在線狀態(tài)信息傳送給非Jabber系統(tǒng)的用戶。一旦Jabber用戶成功注冊(cè),傳輸器就需要知道該用戶什么時(shí)候上線,因此,它發(fā)送一個(gè)在線狀態(tài)信息訂閱請(qǐng)求給該用戶。一個(gè)特殊的帶有“from”特性的在線狀態(tài)信息訂閱數(shù)據(jù)包從傳輸器產(chǎn)生并發(fā)送,其中的數(shù)據(jù)必須可以登錄到本地協(xié)議。
Jabber服務(wù)器包含一個(gè)所有用戶的訂閱信息組成的名單(該名單通常直接存放與文件系統(tǒng)中,盡管這些信息一個(gè)可以存放在數(shù)據(jù)庫(kù)中)。這個(gè)名單被命名為花名冊(cè),很像其他IM系統(tǒng)中的“好友列表”。Jabber的花名冊(cè)存放在服務(wù)器上,這樣用戶就可以自由的從一個(gè)地方到另一個(gè)地方,從一臺(tái)計(jì)算機(jī)到另一臺(tái)計(jì)算機(jī)自由的調(diào)用它。Jabber服務(wù)器根據(jù)用戶意愿對(duì)花名冊(cè)上的對(duì)應(yīng)訂閱關(guān)系進(jìn)行允許、拒絕等操作。花名冊(cè)還包括一些用戶特殊的其它信息,比如用戶的昵稱,以及用戶所屬的群組。這些信息可以通過客戶端調(diào)用適當(dāng)接口顯示花名冊(cè)時(shí)顯現(xiàn)出來。
在Jabber里,有許多不同的實(shí)體需要進(jìn)行相互通信。這些實(shí)體可以表現(xiàn)為傳輸器、群組聊天室、或者是單一的Jabber用戶。Jabber IDs是內(nèi)外結(jié)合的表示用戶身份或路由信息。Jabber IDs的關(guān)鍵特性包括:
它們唯一確定進(jìn)行即時(shí)消息和在線信息狀態(tài)通信的獨(dú)立對(duì)象或?qū)嶓w
用戶很容易記住它們并在真實(shí)世界中進(jìn)行表達(dá)
它們很靈活,以至于可以包容其它IM和在線信息狀態(tài)表。
每一個(gè)Jabber ID(或JID)包括一套有序的元素。JIDs由域、節(jié)點(diǎn)、數(shù)據(jù)流格式的資源組成:
[node@]domain[/resource]
Jabber ID 元素有以下定義:
域名是第一標(biāo)識(shí)符。它表明實(shí)體連接的Jabber服務(wù)器。每一個(gè)可用的Jabber域名都應(yīng)擁有一個(gè)完整的域名。
節(jié)點(diǎn)是第二標(biāo)識(shí)符。它表明“用戶”本身。所有的節(jié)點(diǎn)都對(duì)應(yīng)一個(gè)精確的域。不過,節(jié)點(diǎn)是可選的,一個(gè)精確的域(如conference.jabber.org)是非法Jabber ID。
資源是可選的第三標(biāo)識(shí)符。所有資源都屬于一個(gè)節(jié)點(diǎn)。在Jabber中,資源被用來識(shí)別屬于用戶的特殊對(duì)象,比如設(shè)備或位置。資源是一個(gè)單獨(dú)的用戶可以同時(shí)擁有幾個(gè)與同一Jabber服務(wù)器的連接;如:juliet@capulet.com/balcony vs. juliet@capulet.com/chamber.
一個(gè)Jabber用戶通常通過一個(gè)特殊的資源與服務(wù)器相連,因此在連接時(shí)有一個(gè)node@domain/resource形式的地址(如juliet@capulet.com/balcony)。由于資源時(shí)會(huì)話性的,用戶的地址可以和類似node@domain(如juliet@capulet.com)進(jìn)行通信,就象人們使用和它相同的形式的email一樣。
注意雖然在有些情況下,消息可以直接發(fā)送到一個(gè)精確資源,但總的來說,一個(gè)發(fā)往juliet@capulet.com消息根據(jù)Jabber服務(wù)器上的規(guī)則進(jìn)行路由,因?yàn)槊恳粋€(gè)連接實(shí)例都有它自己的優(yōu)先級(jí)設(shè)定。這樣,如果一條消息正好是發(fā)送給juliet@capulet.com(即沒有指定任一資源),該消息路由到擁有最高優(yōu)先級(jí)的資源,如:juliet@capulet.com/balcony。
1.2版的服務(wù)器增加了一個(gè)成為服務(wù)器回滾的功能。這個(gè)功能是設(shè)計(jì)用來服務(wù)器欺騙的,這樣就為服務(wù)器-服務(wù)器之間的交互增加了一個(gè)額外的安全方法。關(guān)于這個(gè)功能的詳細(xì)信息會(huì)在這個(gè)文檔的未來版本中提供。下面網(wǎng)址提供了一些初步的文檔:http://docs.jabber.org/draft-proto/html/dialback.html.
本文檔提供了一個(gè)Jabber系統(tǒng)結(jié)構(gòu)的高階的概述。如果你對(duì)本文檔有什么疑問,請(qǐng)直接通過stpeter@jabber.org以email或Jabber與文檔的作者(Peter-Saint-Andre)進(jìn)行聯(lián)系。
聯(lián)系客服