原文地址:
http://cometd.org/documentation/2.x/concepts
CometD 2概念
由sbordet提交的關(guān)于2011年8月23日,星期二 - 16:05。
CometD 2概念
CometD項(xiàng)目實(shí)現(xiàn)各種comet的技術(shù),提供可伸縮的Web消息系統(tǒng),可以運(yùn)行在HTTP或其他新興協(xié)議,如WebSocket的網(wǎng)頁(yè)協(xié)議。
定義
讓我們定義客戶端為發(fā)起連接的實(shí)體,服務(wù)器接受連接的實(shí)體。
建立連接是持久的 - 也就是說(shuō),它仍然打開(kāi),直至任何一方?jīng)Q定關(guān)閉它。
典型的客戶端瀏覽器(畢竟,我們?cè)?/span>Web環(huán)境),但也可能是其他應(yīng)用程序,如Java應(yīng)用程序,瀏覽器插件應(yīng)用程序(如Silverlight),或在任何腳本語(yǔ)言的腳本。
根據(jù)comet的技術(shù),客戶端可能會(huì)打開(kāi)多個(gè)物理連接,連接服務(wù)器,但我們可以假設(shè)客戶端和服務(wù)器之間只存在一個(gè)邏輯頻道。
CometD項(xiàng)目使用Bayeux協(xié)議在客戶端和服務(wù)器之間進(jìn)行信息交流。
交換信息的單位是Bayeux message,它是JSON格式。
message包含幾個(gè)字段,其中有些是Bayeux協(xié)議授權(quán),而其他的可能由應(yīng)用程序添加。
一個(gè)字段是一個(gè)鍵/值對(duì),比方說(shuō)message有一個(gè)foo的字段,意味著該message有一個(gè)字段,其鍵是字符串“foo”。
所有客戶端和服務(wù)器之間交換的消息,都有一個(gè)頻道領(lǐng)域。
有3種頻道:(meta channel)元數(shù)據(jù)頻道,(service channel)服務(wù)頻道和(broadcast channel)廣播頻道。
元數(shù)據(jù)頻道由Bayeux創(chuàng)建實(shí)現(xiàn),應(yīng)用程序不能創(chuàng)建新的元數(shù)據(jù)頻道。
服務(wù)頻道和廣播頻道是由應(yīng)用程序創(chuàng)建的,他們可以在任何時(shí)間創(chuàng)建,并且很有必要。
頻道是由一個(gè)字符串代表,并且類似URL路徑,例如:/meta/handshake,/service/game , /foo/bar。
一個(gè)頻道以/meta/開(kāi)頭則它是元數(shù)據(jù)頻道,一個(gè)頻道以/service/開(kāi)頭則它是服務(wù)頻道,而所有其他的頻道則是廣播頻道。
一個(gè)消息頻道領(lǐng)域是元數(shù)頻道則里面的消息是元數(shù)據(jù)消息,同樣的,有服務(wù)頻道消息和廣播頻道消息。
高層次視圖
CometD實(shí)現(xiàn)Web消息傳遞系統(tǒng),特別是Web消息傳遞系統(tǒng)是基于(publish)發(fā)布/(subscribe)訂閱范式的。
在(publish)發(fā)布/(subscribe)訂閱消息傳遞系統(tǒng)中,publish發(fā)出消息,這些消息被賦予類的特點(diǎn)。Subscribe表示的是訂閱他們感興趣的一個(gè)或多個(gè)類的消息,并接收他們訂閱的興趣相匹配的唯一消息。發(fā)送消息的人,在一般情況下,不知道收件人或多個(gè)收件人將收到他們發(fā)布的消息。
在CometD中,頻道領(lǐng)域提供已經(jīng)類化的消息。
頻道是CometD的中心概念:發(fā)布者把消息發(fā)送到頻道里,訂閱者訂閱這個(gè)頻道來(lái)接收消息。
這些將會(huì)在CometD API中有詳細(xì)反映,我們可以去查看。
消息系統(tǒng)的功能之一是他們的拓?fù)浣Y(jié)構(gòu), CometD實(shí)現(xiàn)的是樞紐發(fā)言的拓?fù)浣Y(jié)構(gòu)。
在默認(rèn)配置下,表示有一個(gè)中央服務(wù)器(中心),并且所有客戶端通過(guò)管道鏈接(輻條)連接到該服務(wù)器。如圖:
在CometD中,服務(wù)器接受來(lái)自發(fā)布者發(fā)送的消息,如果消息的頻道是一個(gè)廣播頻道,則服務(wù)器會(huì)轉(zhuǎn)發(fā)該消息給所有訂閱這個(gè)頻道的訂閱者。
CometD服務(wù)器的元數(shù)據(jù)消息和服務(wù)消息會(huì)被特殊處理,不重新路由到任何用戶(實(shí)際上,默認(rèn)情況下,元數(shù)據(jù)頻道是被禁止訂閱的,它是一個(gè)無(wú)操作訂閱服務(wù)頻道) 。
例如,讓我們想象,clientAB訂閱頻道/ A和/ B,clientB訂閱通道/ B
如果發(fā)布者發(fā)布一個(gè)消息到頻道/ A,只有clientAB將接收它。另一方面,如果發(fā)布者發(fā)布一個(gè)消息到頻道/ B,則clientAB和clientB都將收到消息。此外,如果發(fā)布者發(fā)布一個(gè)消息到頻道/ C,則clientAB和clientB都不會(huì)收到的消息,而它將會(huì)結(jié)束其在服務(wù)器上的剛剛開(kāi)始的征程。
重新路由廣播消息是服務(wù)器的默認(rèn)行為,而且它不需要任何應(yīng)用程序代碼進(jìn)行重新路由。
從高層次來(lái)看,那么,你會(huì)看到消息通過(guò)客戶端和服務(wù)器之間的管道來(lái)回流動(dòng)。
一個(gè)單一的廣播消息到達(dá)服務(wù)器,就重新路由到所有客戶端,你可以想像成:當(dāng)它在服務(wù)器上時(shí),該消息是復(fù)制一個(gè)副本發(fā)送到每個(gè)客戶端(盡管,初一效率的原因,這不完全會(huì)發(fā)生)。如果發(fā)件人也是訂閱的這個(gè)頻道的人,它也會(huì)收到發(fā)布消息的副本。
有懸而未決的問(wèn)題,但:
如果元數(shù)據(jù)消息和服務(wù)消息的旅程在服務(wù)器上結(jié)束,應(yīng)用程序可以利用他們來(lái)做些什么,?
一個(gè)客戶端怎么與其他的,特殊的客戶端進(jìn)行連接?
服務(wù)器可以是發(fā)布消息的發(fā)布者嗎?
為了回答這些問(wèn)題和其他問(wèn)題,我們需要采取細(xì)看CometD是如何工作的。繼續(xù)往下閱讀。
一個(gè)較低的水平視圖
在下面的章節(jié)中,我們將采取深入探討CometD是如何實(shí)施工作的。
現(xiàn)在應(yīng)該明確,CometD,它的中心,是一個(gè)客戶端/服務(wù)器系統(tǒng),是通過(guò)了一項(xiàng)協(xié)議,Bayeux協(xié)議進(jìn)行通信的。
在CometD實(shí)現(xiàn)中,客戶端/服務(wù)器通信的捕獲是用半對(duì)象加協(xié)議模式:當(dāng)在客戶端上的半對(duì)象建立與服務(wù)器的通信管道時(shí),其通信半對(duì)象也在服務(wù)器上創(chuàng)建,形成兩條通道- 邏輯 –連接。
在CometD中,這種格局的變化是因?yàn)橛谐橄髠鬏斚ⅲ鋈敕?wù)器的需要。
傳輸可以基于HTTP協(xié)議,也可以基于最近CometD版本的WebSocket協(xié)議(及更多的傳輸可插入)。
從廣義上講,“客戶”是由客戶端的半對(duì)象(用JavaScript類化的org.cometd.Cometd對(duì)象,和用Java類化org.cometd.bayeux.client.ClientSession的對(duì)象)
和客戶端的傳輸(用JavaScript類化的org.cometd.Transport對(duì)象和用Java類化的org.cometd.client.transport.ClientTransport對(duì)象)組成的。
“服務(wù)器”是一個(gè)更復(fù)雜的實(shí)體,由一個(gè)org.cometd.bayeux.server.BayeuxServer實(shí)例,服務(wù)器傳輸(org.cometd.bayeux.server.ServerTransport類)的消息處理組件,一個(gè)服務(wù)器端的半對(duì)象(org.cometd.bayeux.server.ServerSession類)庫(kù)和頻道(org.cometd.bayeux.server.ServerChannel)庫(kù)組成。如下圖:
消息流
客戶端的半對(duì)象把消息傳遞委托給一個(gè)客戶端傳輸,客戶端傳輸負(fù)責(zé)建立與服務(wù)器的頻道,并發(fā)送該頻道的消息。
在服務(wù)器上,它是服務(wù)器傳輸,接收消息。
服務(wù)器傳輸委托一個(gè)消息進(jìn)程給消息處理組件,以處理傳入消息,它生成一個(gè)消息的回復(fù),并又委托該服務(wù)器傳輸把回復(fù)交付給客戶端。
在上圖中,可以看到導(dǎo)管連接的客戶端傳輸和服務(wù)器傳輸,此外ServerSession可能參與(只發(fā)送,而不是直接接收)發(fā)送消息到客戶端(通過(guò)服務(wù)器傳輸)。
TODO:解釋廣播消息流是如何工作的,但是這需要引入服務(wù)器會(huì)話隊(duì)列的概念
Bayeux協(xié)議
客戶端與服務(wù)器交換的Bayeux消息。
Bayeux協(xié)議的要求,一個(gè)新的客戶端發(fā)送的第一條消息是一個(gè)握手消息(/meta/handshake頻道上發(fā)送的消息)。
在服務(wù)器上,如果傳入的握手消息的處理是成功的,然后BayeuxServer創(chuàng)造了一個(gè)半服務(wù)器端對(duì)象的實(shí)例(一個(gè)ServerSession),在服務(wù)器上,客戶端發(fā)起握手。
當(dāng)握手處理完成后,服務(wù)器發(fā)送回給客戶端一個(gè)答復(fù)。
客戶端進(jìn)程的握手消息的答復(fù),如果它是成功,開(kāi)始 - 在幕后 - 與服務(wù)器的心跳機(jī)制,來(lái)交換連接的消息。
這個(gè)心跳機(jī)制的細(xì)節(jié)取決于客戶端上使用的傳輸工具,可以作為客戶端發(fā)送連接消息,并期待回復(fù),一段時(shí)間后,看到(使用HTTP傳輸時(shí),心跳機(jī)制也被稱為“長(zhǎng)輪詢”) 。
心跳機(jī)制,允許客戶端檢測(cè)服務(wù)器是否關(guān)閉了(客戶端將無(wú)法接收來(lái)自服務(wù)器的連接的消息答復(fù)),并允許服務(wù)器檢測(cè)客戶端是否關(guān)閉了(服務(wù)器將不會(huì)收到客戶端的連接消息請(qǐng)求)。
客戶端和服務(wù)器之間的連接的消息一直都有,直至任何一方?jīng)Q定中斷并發(fā)送一個(gè)disconnect的消息(發(fā)送/meta/disconnect斷開(kāi)通道消息)。
聯(lián)系客服