|
英文原文:Reverse Ajax, Part 3: Web servers and Socket.IO
前言
時至今日,用戶期待的是可通過web訪問快速、動態(tài)的應(yīng)用。這一文章系列展示了如何使用反向Ajax(Reverse Ajax)技術(shù)來開發(fā)事件驅(qū)動的web應(yīng)用。系列的第1部分介紹了反向Ajax、輪詢(polling)、流(streaming)、Comet和長輪詢(long polling)。你已經(jīng)了解了Comet是如何使用HTTP長輪詢的,這是可靠地實(shí)現(xiàn)反向Ajax的最好方式,因?yàn)楝F(xiàn)有的所有瀏覽器都提供支持。系列的第2部分說明了如何使用WebSocket來實(shí)現(xiàn)反向Ajax,一些代碼例子被用來幫助說明WebSocket、FlashSocket、服務(wù)器端的約束、請求作用域(request-scoped)服務(wù)以及暫停長生存期請求等。
在本篇文章中,我們深入細(xì)節(jié),討論在web應(yīng)用中使用不同web容器和API(Servlet 3.0和Jetty Continuations)的Comet和WebSocket,了解如何通過使用諸如Socket.IO一類的抽象庫來透明地使用Comet和Websocket。Socket.IO使用功能檢測來確定連接是使用WebSocket、Ajax長輪詢、Flash還是其他方式來建立。
前提條件
理想情況下,要充分體會本文的話,你應(yīng)該對JavaScrpit和Java有一定的了解。本文中創(chuàng)建的例子是使用Google Guice來構(gòu)建的,這是一個使用Java編寫的依賴注入框架。若要讀懂文中所談內(nèi)容,你應(yīng)該要熟悉諸如Guice、Spring或是Pico一類的依賴注入框架的概念。
若要運(yùn)行本文中的例子,你還需要最新版本的Maven和JDK(參見參考資料)。
Comet和WebSocket的服務(wù)器端解決方案
你在第1部分內(nèi)容中已經(jīng)了解到了,Comet(長輪詢或是流)需要服務(wù)器端能夠暫停某個請求,并在一個可能的長延遲之后恢復(fù)或是完成該請求。第2部分內(nèi)容描述了服務(wù)器端如何使用非阻塞式的I/O功能來處理大量的連接,以及它們只能使用線程來服務(wù)請求(每個請求一個線程模式)。你也已經(jīng)了解到了WebSocket的使用是服務(wù)器端依賴的,且并非所有的服務(wù)器都支持WebSocket。
本節(jié)內(nèi)容說明了如果適用的話,那么在Jetty、Tomcat和Grizzly等web服務(wù)器上是如何使用Comet和WebSocket的。本文提供的源代碼包含了Jetty和Tomcat的一個聊天web應(yīng)用例子。本節(jié)內(nèi)容還討論了下面的這些應(yīng)用服務(wù)器:Jboss、Glassfish和WebSphere所支持的API。
Jetty
Jetty是一個web服務(wù)器,支持Java Servlet 3.0規(guī)范、WebSocket和其他的許多集成規(guī)范。Jetty:
1. 功能強(qiáng)大且靈活
2. 易于嵌入
3. 支持虛擬主機(jī)、會話集群和許多可很容易地通過用于Google App Engine的托管服務(wù)的Java代碼或是XML來配置的功能。
核心的Jetty項目由Eclipse Foundation打理。
從版本6開始,Jetty加入了一個被稱作Jetty Continuation(Jetty延續(xù))的異步API,該API允許請求被暫停并在之后被恢復(fù)。表1給出了所支持的規(guī)范和Jetty的主要版本系列的API之間的一個對照關(guān)系。
表1. Jetty的版本和支持
Supports | Jetty 6 | Jetty 7 | Jetty 8 |
---|---|---|---|
Non-blocking I/O | X | X | X |
Servlet 2.5 | X | X | X |
Servlet 3.0 | X | X | |
Jetty Continuations (Comet) | X | X | X |
WebSockets | X | X |
若要實(shí)現(xiàn)使用Comet的反向Ajax的話,你可以使用Jetty的Continuation API,如清單1所示:
清單1. 用于Comet的Jetty Continuation API
// 暫停一個來自servlet方法(get、post......)的請求:protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Continuation continuation = ContinuationSupport.getContinuation(req);
// 可選的做法,設(shè)置超時以避免請求掛起過久
continuation.setTimeout(0);
// 掛起請求
continuation.suspend();
// 保存引用,以備將來另一線程使用
continuations.offer(continuation);
}
// 然后,來自另一個想給客戶發(fā)送事件的線程:
while (!continuations.isEmpty()) {
Continuation continuation = continuations.poll();
HttpServletResponse response =
(HttpServletResponse) continuation.getServletResponse();
// 向響應(yīng)中寫入
continuation.complete();
}
it知識庫:反向Ajax,第3部分:Web服務(wù)器和Socket.IO,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。