張帆,劉嵩
在傳統(tǒng)Web MVC架構模式中,人們往往指的是服務器端MVC,而忽略了瀏覽器端MVC。這是人們對MVC架構模式認識上的局限。由于它只注重服務器端功能,使得瀏覽器端 Web表現(xiàn)層的靈活性不夠,無法實時交互數(shù)據(jù)。針對這個問題,我們引入現(xiàn)代Web MVC架構模式。它通過構建瀏覽器端MVC和服務器端MVC,提高了Web交互數(shù)據(jù)的實時性,同時增強了瀏覽器端 Web表現(xiàn)層的異步通信能力和靈敏度。
本文通過對經典MVC架構模式的簡要分析和歸納,闡明了MVC在軟件開發(fā)中的重要作用。針對人們對傳統(tǒng)Web MVC模式認識上的局限,分析討論了現(xiàn)代Web MVC架構模式的優(yōu)勢。最后結合具體應用,進一步比較了Ajax、Comet等 Web架構模式的有效性,為軟件開發(fā)者和架構師提供了有益的參考。
MVC英文即 Model-View-Controller,它是為編程語言Smalltalk-80發(fā)明的一種目前廣泛流行的軟件設計模式,主要包含三個層面:模型(Model),視圖(View),控制器(Controller)。使用MVC的目的是將創(chuàng)建和操作數(shù)據(jù)的代碼分離即模型、視圖、控制器的分離。
然而傳統(tǒng)Web MVC架構模式面臨二個問題:一是服務器端接收請求后通過控制器從模型中獲取相應數(shù)據(jù)并生成視圖,再response到客戶端,若頁面進行局部刷新,就不得不發(fā)送整個頁面的數(shù)據(jù),這就包含了大量冗余信息。征對這個問題,我們引入Ajax客戶端增強技術,這將在第三節(jié)進行討論;二是由于服務器端主要是采用分布式結構,因此當服務器端模型變化后,它無法立即在服務器端將變化的數(shù)據(jù)即時發(fā)送給客戶端。因而存在實時性不足,頁面內容無法自動更新等問題。通過引入Comet服務器端push技術可以解決這個問題,這將在第四節(jié)進行討論。
客戶端與服務器端在進行數(shù)據(jù)交互過程中,MVC架構實際應用在Browser-Server二端,即瀏覽器端MVC和服務器端MVC。服務器端控制器接收到用戶請求后,從數(shù)據(jù)模型中取出相應數(shù)據(jù)并生成服務器端視圖,再response到客戶端。此時服務器端視圖V2實際上包括了瀏覽器端視圖V1、瀏覽器端控制器 C1、以及少量數(shù)據(jù)模型 M1,即V2={V1+C1+M1},從而構建了瀏覽器端MVC架構,如圖1所示。
由圖1可以看出,服務器發(fā)送給瀏覽器的就不僅僅是呈現(xiàn)給客戶的視圖,而是具有業(yè)務邏輯和控制器處理功能的XML數(shù)據(jù)代碼。服務器發(fā)送 XML數(shù)據(jù)后,首先由瀏覽器端控制器和數(shù)據(jù)模型獲取并由控制器進行相應處理,最后生成瀏覽器端視圖呈現(xiàn)給用戶。當用戶發(fā)送請求時,可將請求交給瀏覽器端控制器處理,由瀏覽器端控制器與服務器進行數(shù)據(jù)交互。
通過使用 Ajax客戶端增強技術,構建瀏覽器端 MVC架構模式,來彌補Web客戶端交互能力不足的問題。
Ajax全稱為“Asynchronous JavaScript and XML”,是指一種創(chuàng)建交互式網(wǎng)頁應用的網(wǎng)頁開發(fā)技術。具體包括:基于XHTML 和CSS標準的表示、使用 Document Object Model進行動態(tài)顯示和交互、使用XML HttpRequest與服務器進行異步通信、使用JavaScript進行綁定。其中Ajax 最主要的特征就是XML HTTPRequest 對象的使用和DOM 的處理。
通過引入Ajax技術,構建了瀏覽器端MVC架構。主要表現(xiàn)在:通過使用XML HttpRequest,可以在瀏覽器端通過發(fā)送HTTP請求與后臺服務器進行動態(tài)異步數(shù)據(jù)交互。當用戶在當前頁面發(fā)送一個請求后,它可以通過Ajax的XML HttpRequest向服務器端控制器進行異步請求,然后控制器從數(shù)據(jù)模型中獲取相關數(shù)據(jù)并生成服務器端視圖,并response到瀏覽器端。瀏覽器端Ajax獲取服務器端的XML文件后,將其解析并存儲在文檔對象模型(DOM)中,最后生成當面頁面呈現(xiàn)給用戶。這樣用戶再進行一些數(shù)據(jù)處理時,可以通過Ajax技術直接從Ajax的文檔數(shù)據(jù)模型(DOM)中獲取數(shù)據(jù),而不必再發(fā)送一個請求到服務器端。只有確定需要從服務器讀取新數(shù)據(jù)時才由Ajax引擎代為向服務器提交請求。這樣通過引用Ajax技術便在瀏覽器端實現(xiàn)了控制器,數(shù)據(jù)模型以及視圖的功能。這便是瀏覽器端MVC架構模式。
瀏覽器端控制器組件可以通過 Ajax的 XML HttpRequest技術來異步發(fā)送請求,使得瀏覽器與服務器的數(shù)據(jù)交互可以異步交互傳輸。這樣可以不用刷新整個頁面就能與服務器端進行數(shù)據(jù)交互,使得客戶端看起來像即時響應的桌面程序那樣,加快了瀏覽器的響應速度,節(jié)省了用戶等待時間。圖2為基于Ajax技術的Web交互過程。
由圖2可以看出,瀏覽器呈現(xiàn)給用戶的是連續(xù)響應的,基于Ajax應用程序的數(shù)據(jù)的顯示和傳輸是異步進行的。當數(shù)據(jù)請求或數(shù)據(jù)傳輸正在進行時,原來的數(shù)據(jù)顯示界面可以不受影響。即Ajax程序可以僅向服務器端發(fā)送并取回必需的數(shù)據(jù),同時很多處理工作可以在瀏覽器端完成。因此瀏覽器端MVC架構模式可以在很大程度上提高Web表現(xiàn)層的交互能力。
為了提高 Web交互數(shù)據(jù)的實時性,本節(jié)介紹了 Comet技術,來對服務器端MVC架構模式進行改進,增強服務器端的MVC數(shù)據(jù)處理能力。
盡管通過引入Ajax技術,用戶可以動態(tài)異步地向服務器發(fā)出請求。但這種請求無法保證客戶端獲取的數(shù)據(jù)是最新的。因為數(shù)據(jù)模型可能在服務器端發(fā)出信息后就進行了更新,因此無法進行實時通信。
為了解決Ajax實時性不足的問題,我們可以使用二種方法:第一種是瀏覽器每隔一段時間向服務器發(fā)出輪詢以進行更新,即輪詢方法;第二種方法是服務器始終打開與瀏覽器的連接并在數(shù)據(jù)更新時立即發(fā)送給瀏覽器的長連接技術,即Comet技術。
輪詢方法的主要缺陷: 為使客戶端瀏覽器刷新當前頁面,多長時間去服務器查詢成了問題。高頻率輪詢會使網(wǎng)絡承載過重,影響服務器速率;低頻率輪詢又會錯過更新或傳送一些失去時效的信息。因此使用Comet技術則優(yōu)勢明顯,它不會產生大量通信量。同時在數(shù)據(jù)發(fā)生改變時,可將即時數(shù)據(jù)實時地“推送”給客戶端。下文將詳細介紹 Comet技術。
Comet就是一種服務器端 push技術,就是當客戶端向服務器發(fā)送一個請求后,服務器接受它,并使用一個無限循環(huán)將客戶端所需的數(shù)據(jù)push到response中,只要response不關閉,服務器就會將更新的數(shù)據(jù)推送給客戶端。它通過保持一個長期即時更新的連接,持續(xù)從服務器端獲取新的信息,由此實現(xiàn)實時通信。
Comet來源于Publish/Subscribe 設計模式,使得服務器端數(shù)據(jù)與客戶端數(shù)據(jù)時刻保持一致。若數(shù)據(jù)發(fā)生更新,則服務器端必須將這些更改后的數(shù)據(jù)傳送出去以達到對象間的同步。
通過引入Comet,使得客戶端必須在異步初始化到服務器端的連接時保持工作。在服務器端,即使不能馬上對請求做出回應,連接也要保持直到服務器端相關數(shù)據(jù)發(fā)生改變。當數(shù)據(jù)模型發(fā)生變化時,服務器端通過之前已經建立好的連接把產生變化的數(shù)據(jù)推送到客戶端。如果存在并發(fā)的多個事件,服務器便可在此連接上發(fā)送多個事件數(shù)據(jù)而無需客戶端每次都明確發(fā)出請求,Comet工作模式如圖3。
圖3顯示的Comet應用程序異步響應模式圖。從圖中我們可以看出,服務器端可以在任意時刻向客戶端發(fā)送數(shù)據(jù),而不需要等待客戶的請求。數(shù)據(jù)在一個預先打開的管道上傳送,這種方法可以大幅度減少數(shù)據(jù)傳輸?shù)难舆t。若數(shù)據(jù)有所更新,服務器便可即時將數(shù)據(jù)推送到客戶端。因此Comet的引入,增強了服務器處理實時數(shù)據(jù)的能力。
學生宿舍管理系統(tǒng)以MyEclipse6.0作為開發(fā)平臺,數(shù)據(jù)庫用的是Oracle9i,使用的編程語言有Java,Jsp,JavaScript,DWR2.0,Ext JS等。
本系統(tǒng)通過在客戶端引入Ajax技術,構建了瀏覽器端MVC架構。在客戶端與服務器之間創(chuàng)建了Ext JS腳本文件,使得宿舍管理員向服務器發(fā)出請求時,由Ext JS腳本文件單獨與后臺服務器建立連接,實現(xiàn)了動態(tài)異步數(shù)據(jù)交互。如圖4所示,若進行樓棟,舍區(qū),收費標準,性別等信息進行設置時,管理員不需要向服務器發(fā)出請求,而是直接從瀏覽器端 Model獲取信息。當管理員需要再次讀取曾經讀取過的信息,則可直接從瀏覽器端Ajax文檔數(shù)據(jù)模型(DOM)中獲取,而不必再次與服務器進行交互。只有當宿舍管理員需要獲取新的數(shù)據(jù)時,才由Ajax引擎與服務器進行數(shù)據(jù)交互處理。
圖4 房間信息管理
通過使用jetty構建Comet服務器對系統(tǒng)進行改進,使得宿舍管理員在進行數(shù)據(jù)操作時獲取的數(shù)據(jù)更具有實時性。由于采用分布式結構,當多個宿舍管理員同時操作本系統(tǒng)時,往往他們會對同一對象進行操作。顯示效果如圖5,從圖中可以看到當某一樓棟的某一房間的待住人數(shù)為1時,其中一個管理員對其進行了添加使得服務器端此房間待住人數(shù)變?yōu)?。這意味著其他管理員的當前操作頁面也必須實時地更新此信息,才能確保數(shù)據(jù)的準確。在 Comet架構模式應用中,一旦服務器發(fā)現(xiàn)有數(shù)據(jù)更新,它就主動把最新的數(shù)據(jù)以“推送”的方式發(fā)送到客戶端,使得宿舍管理員獲取的數(shù)據(jù)更及時,更具有實時性。同時也避免了宿舍管理員為了獲取實時信息,而多次刷新當前頁面。
圖5 添加學生入住信息界面
利用 Ajax技術在表現(xiàn)層的優(yōu)勢,構建瀏覽器端 MVC架構,增強了客戶端動態(tài)交互能力。同時應用 Comet架構模式構建后臺服務器,實現(xiàn)了實時通信。在學生宿舍管理系統(tǒng)中,通過使用Ajax和Comet技術,使得系統(tǒng)在功能上都得到明顯改進和提高。
[1]陳鄭偉,彭巖,莊力可.基于 Ajax 的電子政務平臺的研究與應用[J].計算機工程與應用,2007 ,43 (5):1962199.
[2]Wilkins Greg.Ajax ,Comet and J etty.[2006211202].[EB/OL].http://www.webtide.com/downloads/whitePaperAjaxJetty.html,2006.
[3]周牧,談曉軍,左 翔,崔雨勇.基于AJAX和XML 的WebGIS 系統(tǒng)研究.計算機工程,2009,7.
[4]Garret J J.AJAX: New Approach to Web Applications[J/OL].(2005-02-18).http://www.adaptivepath.com/publications/essays/archives/000385.
[5]王默玉,劉巖,劉林,李成榕,王輝.Web2.0-Comet-Continuations 模式在局部放電實時監(jiān)測中的應用[J].吉林大學學報(工學版)2009,1 第39卷第1期.
[6]劉鑫,陳偉.基于AJAX和Server Push的Web樹組件設計與實現(xiàn)[J].計算機工程與設計,2009,30(3).