劉媚++王旭陽
摘要:Comet技術(shù)也稱反向AJAX技術(shù),它主要是通過服務(wù)器端主動(dòng)推送,解決AJAX需定期輪詢發(fā)送消息請(qǐng)求連接所要消耗服務(wù)器資源的問題,給用戶實(shí)時(shí)交互使用帶來了全新的體驗(yàn)。文章主要介紹Comet技術(shù)、實(shí)現(xiàn)方式、實(shí)現(xiàn)框架等,使用Comet技術(shù)完成實(shí)時(shí)系統(tǒng)的開發(fā)方法和步驟。主要是通過開源的Pushlet框架技術(shù)相結(jié)合完成網(wǎng)頁主動(dòng)推送的功能,實(shí)現(xiàn)網(wǎng)頁數(shù)據(jù)實(shí)時(shí)主動(dòng)呈現(xiàn)給用戶的最終效果。
關(guān)鍵詞:Comet;AJAX;服務(wù)器推送;Web實(shí)時(shí)系統(tǒng)
隨著互聯(lián)網(wǎng)技術(shù)的快速發(fā)展,瀏覽器作為Web應(yīng)用前臺(tái)的方式越來越多。人們對(duì)網(wǎng)頁的使用要求不僅僅是主動(dòng)獲取的方式,更多的是希望由服務(wù)器端主動(dòng)推送呈現(xiàn)用戶所需的內(nèi)容。如現(xiàn)在應(yīng)用比較多的淘寶、京東的一些主動(dòng)推送服務(wù)。
AJAX技術(shù)的出現(xiàn)使得Comet技術(shù)成為可能。AJAX技術(shù)的工作原理主要是通過異步方式在客戶端和服務(wù)器端增加了個(gè)中間層,客戶端發(fā)送請(qǐng)求不是所有的都直接提交給服務(wù)器端,某些請(qǐng)求是可以通過中間層間接完成的,這樣在一定程度上緩解了服務(wù)器的負(fù)荷。但是,AJAX最終還是需要服務(wù)器響應(yīng),實(shí)時(shí)性還是有延遲。因此,應(yīng)用AJAX技術(shù)的話,實(shí)時(shí)性還是得不到保障。所以又引入了新的技術(shù)Comet(也叫反向AJAX),Comet通過維護(hù)一條HTTP長(zhǎng)鏈接,從而不再需要客戶端側(cè)發(fā)送請(qǐng)求消息,服務(wù)器端主動(dòng)發(fā)送消息到瀏覽器端。
1 Comet技術(shù)實(shí)現(xiàn)方式
傳統(tǒng)的Ajax技術(shù)無法實(shí)現(xiàn)真正的高并發(fā)、高實(shí)時(shí)性,同時(shí)頻繁的輪詢機(jī)制服務(wù)器的開銷比較大,只能應(yīng)用在小型應(yīng)用中。所以AJAX適用并發(fā)用戶不大于200個(gè),并且用戶不同操作的請(qǐng)求的實(shí)時(shí)性Web應(yīng)用中,如:用戶通過網(wǎng)頁注冊(cè)賬號(hào),當(dāng)輸入用戶名時(shí),提示此用戶名已經(jīng)存在AJAX的典型應(yīng)用。
Comet技術(shù)也被稱作反AJAX (Reverse AJAX)技術(shù),它主要是通過服務(wù)器端推的方式來解決AJAX中存在不確定的延遲以及需要維護(hù)大量開銷的服務(wù)器負(fù)荷問題。而通過Comet技術(shù),客戶端側(cè)則不需要主動(dòng)向服務(wù)器發(fā)起消息,服務(wù)器端卻能主動(dòng)將消息推送到客戶端側(cè)。
因此,Comet被稱為“基于HTTP長(zhǎng)連接的服務(wù)器推”。Comet技術(shù)主要是通過在服務(wù)器端和客戶端側(cè)的瀏覽器之間建立并維持一個(gè)TCP長(zhǎng)連接保持監(jiān)聽的。當(dāng)服務(wù)器側(cè)處理完客戶端發(fā)送過來的請(qǐng)求時(shí),服務(wù)器端并不是馬上關(guān)閉這條連接,而是將這條連接一直保留著,當(dāng)下一次有數(shù)據(jù)更新或者變動(dòng)時(shí),它能快速使服務(wù)器實(shí)時(shí)地將更新的信息通過這條連接傳送到客戶端,而無須客戶端側(cè)再次發(fā)出請(qǐng)求,這種方式節(jié)省了服務(wù)器端與客戶端建立與關(guān)閉連接的時(shí)間,真正實(shí)現(xiàn)了“push”模式。
2 使用Comet技術(shù)的設(shè)計(jì)框架
2.1
Pushlet框架
設(shè)計(jì)采用Pushlet框架實(shí)現(xiàn)。Pushlet框架是Comet技術(shù)應(yīng)用的開源框架。它主要是通過客戶端側(cè)發(fā)送請(qǐng)求,訂閱感興趣的事件。服務(wù)器端為每個(gè)客戶端分配一個(gè)可以用作會(huì)話的ID作為標(biāo)記,事件源會(huì)把新產(chǎn)生的事件以多播的方式發(fā)送到訂閱者的事件隊(duì)列里。Pushlet采用基于Comet的JavaScript庫文件用于實(shí)現(xiàn)長(zhǎng)輪詢方式的“服務(wù)器推”。
2.2 數(shù)據(jù)層
服務(wù)器數(shù)據(jù)推送采用開源的Pushlet框架,利用JSP技術(shù),服務(wù)器在不關(guān)閉http流的情況下推送數(shù)據(jù)到客戶端瀏覽器,基于Comet的長(zhǎng)輪詢方式。首先每個(gè)Client會(huì)跟Server建立一個(gè)長(zhǎng)連接,服務(wù)器會(huì)保存客戶端Session即入隊(duì),Server會(huì)每隔一段時(shí)間例如每5秒對(duì)數(shù)據(jù)庫進(jìn)行查詢,然后根據(jù)隊(duì)列中的對(duì)象進(jìn)行廣播,把數(shù)據(jù)Push到每個(gè)Client。性能說明:Server每5秒只對(duì)數(shù)據(jù)庫進(jìn)行1次查詢,然后把數(shù)據(jù)廣播給所有連接的客戶端,這區(qū)別于AJAX每個(gè)客戶端都去對(duì)數(shù)據(jù)庫進(jìn)行查詢,Push的性能要遠(yuǎn)遠(yuǎn)高于AJAX拉取的方式。在Push的過程中程序會(huì)頻繁開關(guān)數(shù)據(jù)庫,為了減少連接創(chuàng)建時(shí)間,提高性能,連接采用開源連接池組件Proxool。
2.3 業(yè)務(wù)邏輯層
主要使用struts2框架來處理用戶請(qǐng)求,實(shí)現(xiàn)具體邏輯關(guān)系和頁面跳轉(zhuǎn)。
2.4 表現(xiàn)層
圖形化報(bào)表呈現(xiàn)用JfreeChart和FusionCharts作比較,F(xiàn)LASH格式的報(bào)表在色彩表現(xiàn)要比JfreeChart效果好,并且具有動(dòng)態(tài)效果,推薦報(bào)表的呈現(xiàn)方式采用FusionCharts圖表控件。前端頁面展示采用Jpolite框架,JPolite將內(nèi)容展示和事件相分離。
3 使用Pushlet開發(fā)Comet風(fēng)格的Web應(yīng)用
(l)首先當(dāng)然要獲取pushlet開發(fā)包。http://sourceforge.net/projects/pushlets/files/pushlets/2.0.4/pus hlet-2.0.4.zip/download下載后解壓,獲取lib下的pushlet.Jar,pushletclient.Jar及web apps\pu shlet \WEB-INF\classes下的log4j. properties,pushlet. properties、sources. propertieS。
(2)在src目錄中添加log4j.properties,pushlet.properties,sources.properties,后續(xù)對(duì)sources.properties進(jìn)行修改和配置。
(3)配置Web. xml。
(4)創(chuàng)建自己的事件源。
創(chuàng)建事件(pullEvent)中,業(yè)務(wù)部分就寫在pullEvent()方法中即可,這個(gè)方法會(huì)被定時(shí)調(diào)用。protected EventpullEvent(){
Event
event
=Event. creat eDat aEvent("/fornew/push"):∥事件與jsp頁面“綁定” StringBufferstr - new StringBuffer(“工單總量[”).append(i++).append(]):str. append (this.getRandomStr()):
try{//轉(zhuǎn)碼,否則中文在頁面出現(xiàn)亂碼,且會(huì)使頁面“掉線”event. setField("hw", new
String (str.toString(). getBytes ("UTF8"),
"IS08859-1"》:
)
catch (UnsupportedEncodingException e) {
e.printStackTrace():
)
return event;
)∥產(chǎn)生隨機(jī)數(shù),便于頁面觀察
public String getRandomStr(){
Random random = new Random();
return Math. abs (random. nextlnt())+"": )
(5)在上面加入的sources. properties中配置事件源。
配置如下:
sourcel-com. fornew. PushLet $PushEvent
(6)編寫index.jsp頁面如下。
pushlet源碼中DEMO測(cè)試成功的參考頁面如圖1所示。
4 結(jié)語
本文通過采用Comet技術(shù)開源的Pushlet框架實(shí)現(xiàn)Web的實(shí)時(shí)系統(tǒng),給用戶帶來了全新的交互性和良好的界面感知。為了將Comet技術(shù)與現(xiàn)有技術(shù)架構(gòu)相結(jié)合,采用開源的plush框架設(shè)計(jì)結(jié)構(gòu),從而保證節(jié)點(diǎn)快速地加入、退出、跳轉(zhuǎn)等,提高交互的性能。為了解決資源鏈接數(shù)的優(yōu)化設(shè)置,本文采用了Tomcat中間件的應(yīng)用,以達(dá)到最佳資源數(shù)的應(yīng)用,最終更大化地提升系統(tǒng)性能。由于Comet技術(shù)鏈接數(shù)資源有限,只能應(yīng)用于并發(fā)數(shù)較少的鏈接使用,當(dāng)并發(fā)數(shù)較多的情況出現(xiàn),實(shí)時(shí)性就得不到保障。下一步可以考慮將Comet技術(shù)與多并發(fā)分布式技術(shù)相結(jié)合,應(yīng)用于多終端、多用戶的多連接實(shí)時(shí)呈現(xiàn)。