国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
使用Java實現(xiàn)Comet風(fēng)格的Web應(yīng)用一
使用Java實現(xiàn)Comet風(fēng)格的Web應(yīng)用(一)開始
    在本文中,我將展示如何使用各種不同的 Java 技術(shù)構(gòu)建一些簡單的 Comet 風(fēng)格的 Web 應(yīng)用程序。讀者對 Java Servlet、Ajax 和 JavaScript 應(yīng)該有一定的了解。我們將考察 Tomcat 和 Jetty 中一些支持 Comet 的特性,因此需要使用這兩個產(chǎn)品的最新版本。本文使用 Tomcat 6.0.14 和 Jetty 6.1.14.另外還需要一個支持 Java 5 或更高版本的 JDK.本文使用 JDK 1.5.0-16.此外還需要看看 Jetty 7 的預(yù)發(fā)布版,因為它實現(xiàn)了 Servlet 3.0 規(guī)范,我們將在本文中研究該規(guī)范。
    理解 Comet
    您可能已經(jīng)聽說過 Comet,因為它最近受到了一定的關(guān)注。Comet 有時也稱反向 Ajax 或服務(wù)器端推技術(shù)(server-side push)。其思想很簡單:將數(shù)據(jù)直接從服務(wù)器推到瀏覽器,而不必等到瀏覽器請求數(shù)據(jù)。聽起來簡單,但是如果熟悉 Web 應(yīng)用程序,尤其是 HTTP 協(xié)議,那么您就會知道,這絕不簡單。實現(xiàn) Comet 風(fēng)格的 Web 應(yīng)用程序,同時保證在瀏覽器和服務(wù)器上的可伸縮性,這只是在最近幾年才成為可能。在本文的后面,我們將看看一些流行的 Java Web 服務(wù)器如何支持可伸縮的 Comet 架構(gòu),但首先我們來看看為什么要創(chuàng)建 Comet 應(yīng)用程序,以及用于實現(xiàn)它們的常見設(shè)計模式。
    使用 Comet 的動機
    HTTP 協(xié)議的成功毋庸置疑。它是 Internet 上大部分信息交換的基礎(chǔ)。然而,它也有一些局限性。特別是,它是無狀態(tài)、單向的協(xié)議。請求被發(fā)送到 Web 服務(wù)器,服務(wù)器處理請求并發(fā)回一個響應(yīng) — 僅此而已。請求必須由客戶機發(fā)出,而服務(wù)器則只能在對請求的響應(yīng)中發(fā)送數(shù)據(jù)。這至少會影響很多類型的 Web 應(yīng)用程序的實用性。典型的例子就是聊天程序。另外還有一些例子,例如比賽的比分、股票行情或電子郵件程序。
    HTTP 的這些局限性也是它取得一定成功的原因。請求/響應(yīng)周期使它成為了經(jīng)典的模型,即每個連接使用一個線程。只要能夠快速為請求提供服務(wù),這種方法就有巨大的可伸縮性。每秒鐘可以處理大量的請求,只需使用少量的服務(wù)器就可以處理很大數(shù)量的用戶。對于很多經(jīng)典的 Web 應(yīng)用程序,例如內(nèi)容管理系統(tǒng)、搜索應(yīng)用程序和電子商務(wù)站點等等而言,這非常適合。在以上任何一種 Web 應(yīng)用程序中,服務(wù)器提供用戶請求的數(shù)據(jù),然后關(guān)閉連接,并釋放那個線程,使之可以為其他請求服務(wù)。如果提供初始數(shù)據(jù)之后仍可能存在交互,那么將連接保持為打開狀態(tài),因此線程就不能釋放出來,服務(wù)器也就不能為很多用戶服務(wù)。
    但是,如果想在對請求做出響應(yīng)并發(fā)送初始數(shù)據(jù)之后,仍然保持與用戶的交互呢?在 Web 早期,這一點常使用 meta 刷新實現(xiàn)。這將自動指示瀏覽器在指定秒數(shù)之后重新裝載頁面,從而支持簡陋的輪詢(polling)。這不僅是一種糟糕的用戶體驗,而且通常效率非常低下。如果沒有新的數(shù)據(jù)要顯示在頁面上呢?這時不得不重新呈現(xiàn)同樣的頁面。如果對頁面的更改很少,并且頁面的大部分沒有變化呢?同樣,不管是否有必要,都得重新請求和獲取頁面上的一切內(nèi)容。
    Ajax 的發(fā)明和流行改變了上述狀況?,F(xiàn)在,服務(wù)器可以異步通信,因此不必重新請求整個頁面?,F(xiàn)在可以進行增量式的更新。只需使用 XMLHttpRequest 輪詢服務(wù)器。這項技術(shù)通常被稱作 Comet.這項技術(shù)存在一些變體,每種變體具有不同的性能和可伸縮性。我們來看看這些不同風(fēng)格的 Comet.
Comet 風(fēng)格
    Ajax 的出現(xiàn)使 Comet 成為可能。HTTP 的單向性質(zhì)可以有效地加以規(guī)避。實際上有一些不同的方法可以繞過這一點。您可能已經(jīng)猜到,支持 Comet 的最容易的方式是輪詢(poll)。使用 XMLHttpRequest 向服務(wù)器發(fā)出調(diào)用,返回后,等待一段固定的時間(通常使用 JavaScript 的 setTimeout 函數(shù)),然后再次調(diào)用。這是一項非常常見的技術(shù)。例如,大多數(shù) webmail 應(yīng)用程序就是通過這種技術(shù)在電子郵件到達時顯示電子郵件的。
    這項技術(shù)有優(yōu)點也有缺點。在這種情況下,您期望快速返回響應(yīng),就像任何其他 Ajax 請求一樣。在請求之間必須有一段暫停。否則,連續(xù)不斷的請求會沖垮服務(wù)器,并且這種情況下顯然不具有可伸縮性。這段暫停使應(yīng)用程序產(chǎn)生一個延時。暫停的時間越長,服務(wù)器上的新數(shù)據(jù)就需要越多的時間才能到達客戶機。如果縮短暫停時間,又將重新面臨沖垮服務(wù)器的風(fēng)險。但是另一方面,這顯然是最簡單的實現(xiàn) Comet 的方式。
    現(xiàn)在應(yīng)該指出,很多人認為輪詢并不屬于 Comet.相反,他們認為 Comet 是對輪詢的局限性的一個解決方案。最常見的 “真正的” Comet 技術(shù)是輪詢的一種變體,即長輪詢(long polling)。輪詢與長輪詢之間的主要區(qū)別在于服務(wù)器花多長的時間作出響應(yīng)。長輪詢通常將連接保持一段較長的時間 — 通常是數(shù)秒鐘,但是也可能是一分鐘甚至更長。當(dāng)服務(wù)器上發(fā)生某個事件時,響應(yīng)被發(fā)送并隨即關(guān)閉,輪詢立即重新開始。
    長輪詢相對于一般輪詢的優(yōu)點在于,數(shù)據(jù)一旦可用,便立即從服務(wù)器發(fā)送到客戶機。請求可能等待較長的時間,期間沒有任何數(shù)據(jù)返回,但是一旦有了新的數(shù)據(jù),它將立即被發(fā)送到客戶機。因此沒有延時。如果您使用過基于 Web 的聊天程序,或者聲稱 “實時” 的任何程序,那么它很可能就是使用了這種技術(shù)。
    長輪詢有一種變體,這是第三種風(fēng)格的 Comet.這通常被稱為流(streaming)。按照這種風(fēng)格,服務(wù)器將數(shù)據(jù)推回客戶機,但是不關(guān)閉連接。連接將一直保持開啟,直到過期,并導(dǎo)致重新發(fā)出請求。XMLHttpRequest 規(guī)范表明,可以檢查 readyState 的值是否為 3 或 Receiving(而不是 4 或 Loaded),并獲取正從服務(wù)器 “流出” 的數(shù)據(jù)。和長輪詢一樣,這種方式也沒有延時。當(dāng)服務(wù)器上的數(shù)據(jù)就緒時,該數(shù)據(jù)被發(fā)送到客戶機。這種方式的另一個優(yōu)點是可以大大減少發(fā)送到服務(wù)器的請求,從而避免了與設(shè)置服務(wù)器連接相關(guān)的開銷和延時。不幸的是,XMLHttpRequest 在不同的瀏覽器中有很多不同的實現(xiàn)。這項技術(shù)只能在較新版本的 Mozilla Firefox 中可靠地使用。對于 Internet Explorer 或 Safari,仍需使用長輪詢。
    至此,您可能會想,長輪詢和流都有一個很大的問題。請求需要在服務(wù)器上存在一段較長的時間。這打破了每個請求使用一個線程的模型,因為用于一個請求的線程一直沒有被釋放。更糟糕的是,除非要發(fā)回數(shù)據(jù),否則該線程一直處于空閑狀態(tài)。這顯然不具有可伸縮性。幸運的是,現(xiàn)代 Java Web 服務(wù)器有很多方式可以解決這個問題。
    Java 中的 Comet
    現(xiàn)在有很多 Web 服務(wù)器是用 Java 構(gòu)建的。一個原因是 Java 有一個豐富的本地線程模型。因此實現(xiàn)典型的每個連接一個線程的模型便非常簡單。該模型對于 Comet 不大適用,但是,Java 對此同樣有解決的辦法。為了有效地處理 Comet,需要非阻塞 IO,Java 通過它的 NIO 庫提供非阻塞 IO.兩種最流行的開源服務(wù)器 Apache Tomcat 和 Jetty 都利用 NIO 增加非阻塞 IO,從而支持 Comet.然而,這兩種服務(wù)器中的實現(xiàn)卻各不相同。我們來看看 Tomcat 和 Jetty 對 Comet 的支持。
Tomcat 和 Comet
    對于 Apache Tomcat,要使用 Comet,主要需要做兩件事。首先,需要對 Tomcat 的配置文件 server.XML 稍作修改。默認情況下啟用的是更典型的同步 IO 連接器?,F(xiàn)在只需將它切換成異步版本,如清單 1 所示。
    清單 1. 修改 Tomcat 的 server.xml
 <!-- This is the usual Connector, comment it out and add the NIO one --> 
  <!-- Connector URIEncoding="utf-8" connectionTimeout="20000" port="8084" 
protocol="HTTP/1.1" redirectPort="8443"/ --> 
<Connector connectionTimeout="20000" port="8080" protocol="org.apache. 
coyote.http11.Http11NioProtocol" redirectPort="8443"/> 

    Servlet.這顯然是 Tomcat 特有的一個接口。清單 2 顯示了一個這樣的例子。
    清單 2. Tomcat Comet servlet
 public class TomcatWeatherServlet extends HttpServlet implements CometProcessor {
  private MessageSender messageSender = null;
  private static final Integer TIMEOUT = 60 * 1000;
  @Override
  public void destroy() {
  messageSender.stop();
  messageSender = null;
  }
  @Override
  public void init() throws ServletException {
  messageSender = new MessageSender();
  Thread messageSenderThread =
  new Thread(messageSender, "MessageSender[" + getServletContext()
  .getContextPath() + "]");
  messageSenderThread.setDaemon(true);
  messageSenderThread.start();
  }
  public void event(final CometEvent event) throws IOException, ServletException {
  HttpServletRequest request = event.getHttpServletRequest();
  HttpServletResponse response = event.getHttpServletResponse();
  if (event.getEventType() == CometEvent.EventType.BEGIN) {
  request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
  log("Begin for session: " + request.getSession(true).getId());
  messageSender.setConnection(response);
  Weatherman weatherman = new Weatherman(95118, 32408);
  new Thread(weatherman).start();
  } else if (event.getEventType() == CometEvent.EventType.ERROR) {
  log("Error for session: " + request.getSession(true).getId());
  event.close();
  } else if (event.getEventType() == CometEvent.EventType.END) {
  log("End for session: " + request.getSession(true).getId());
  event.close();
  } else if (event.getEventType() == CometEvent.EventType.READ) {
  throw new UnsupportedOperationException("This servlet does not accept
  data");
  }
  }
  }
 
本篇文章來源于:開發(fā)學(xué)院 http://edu.codepub.com   原文鏈接:http://edu.codepub.com/2010/0225/20553.php
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
通過 Tomcat Advanced I/O 獲得高性能的 Ajax
web push
Apache及其http.conf配置相關(guān)資源索引-Web開發(fā)-網(wǎng)站建設(shè)
開發(fā)|JavaWeb應(yīng)用開發(fā)(一)——環(huán)境搭建
Java后端WebSocket的Tomcat實現(xiàn)
Java nginx是Java后臺開發(fā)最常用最入門的技術(shù)嗎?
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服