聶永的博客

          記錄工作/學習的點點滴滴。

          Servlet 3.0筆記之異步請求Comet流推送(Streaming)實現(xiàn)小結(jié)

          Servlet3規(guī)范支持異步請求(或者稱為長連接,或者反向AJAX,或者COMET,或者服務器推送技術):無阻塞的輸入與輸出模型,可以延時的請求和響應功能,還有超時事件通知,看上去一切都是那么完美。
          但終端瀏覽器支持長連接情況差強人意,對Comet的支持大致匯總?cè)缦拢?/div>
          1. IE瀏覽器最佳實踐是使用htmlfile ActiveXObject,以及創(chuàng)建隱藏IFrame組件,可以跨越IE6-IE8;雖IE 8支持XDomainRequest支持HTTP Streaming,但僅僅是IE 8。
          2. Firefox 瀏覽器相當棒,支持XMLHttpRequest Streaming 和隱藏的IFrame組件。
          3. Safari 瀏覽器支持XMLHttpRequest Streaming。
          4. Chrome有些無奈,算不上支持XMLHttpRequest Streaming,使用IFrame的話會一直出現(xiàn)正在加載中的標志。
          5. Opera也不支持XMLHttpRequest Streaming,使用IFrame的話會一直出現(xiàn)正在加載中的標志。
          總之,使用IFrame是一個不錯的方案,在IE、Firefox下表現(xiàn)的很完美,在其它瀏覽器下只能忍受討厭的正在加載中。數(shù)據(jù)交換格式可以采用JS腳本調(diào)用。
          但無論哪一種方案,都必須認識到,一個持久的連接,當頁面內(nèi)容一直在遞增時,會越來越膨脹,會占用用戶機器的CPU,盡量隔一段時間斷開連接,重新請求。
          HTTP 1.1規(guī)范中聲明客戶端不應該與服務器端建立超過兩個 HTTP 連接,因此瀏覽器內(nèi)需要借助腳本避免客戶重開兩個腳本。
          按照目前情形下,需要借助AJAX PULL  + COMET PUSH 相結(jié)合來打造相當好的用戶體驗。
          Servlet本身,無論2.4或者2.5的版本,可以使用一個循環(huán)達到長連接的目標:
          /**
          * 一個典型的長連接實現(xiàn)
          *
          * @author yongboy
          * @date 2011-1-14
          * @version 1.0
          */
          @WebServlet("/demoLongLink")
          public class DemoLongLinkServlet extends HttpServlet {
          private static final long serialVersionUID = 4617227991063927036L;

          protected void doGet(HttpServletRequest request,
          HttpServletResponse response) throws ServletException, IOException {

          response.setHeader("Cache-Control", "private");
          response.setHeader("Pragma", "no-cache");
          response.setHeader("Connection", "Keep-Alive");
          response.setHeader("Proxy-Connection", "Keep-Alive");
          response.setContentType("text/html;charset=UTF-8");

          PrintWriter out = response.getWriter();
          out.println("<div>Start ...</div>");
          out.flush();

          int num = 0;
          int max = 100;
          while (true) {
          out.println("<div>" + (num++) + "</div>");
          out.flush();

          if (num >= max) {
          break;
          }

          try {
          Thread.sleep(1000);
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          }

          out.println("<div>Done !</div>");
          out.flush();
          out.close();
          }
          }
          每一個連接線程都處于一個不斷循環(huán)之中,不能夠有效釋放,相當?shù)睦速M服務器資源,有可能導致容器內(nèi)線程池耗盡,將無法應對后續(xù)請求。同時少了異步連接的特性,無法直接定義超時時間,更不要說超時事件,超時監(jiān)聽器等企業(yè)特性了。
          當然也可以實現(xiàn)異步請求,但可能沒有規(guī)范那般嚴格。
          同步請求的模型:
          對比異步請求模型:
          上面兩張圖借用了涂0實驗室,表示感謝。
          在前兩篇文章中,使用一個單獨線程處理資源,分發(fā)到大部分的異步請求中。

          posted on 2011-01-14 10:26 nieyong 閱讀(2359) 評論(0)  編輯  收藏 所屬分類: Servlet3

          公告

          所有文章皆為原創(chuàng),若轉(zhuǎn)載請標明出處,謝謝~

          新浪微博,歡迎關注:

          導航

          <2011年1月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          統(tǒng)計

          • 隨筆 - 152
          • 文章 - 0
          • 評論 - 310
          • 引用 - 0

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個人收藏

          • 國內(nèi)老牌GreenVPN,翻墻速度確實杠杠的!
          • 個人一直在使用中,在線觀看www.youtube.com上高清視頻一點都不卡。 每個月才18塊錢,一個季度48,再超值提供一個9折優(yōu)惠碼:freevpnssh。 我平常在Linux下安裝/更新軟件,壓根不用擔心GFW阻撓了, 更不用提windows 7了。

          最新隨筆

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 凤山市| 鸡泽县| 左贡县| 托克逊县| 宁化县| 天津市| 漳浦县| 金阳县| 咸阳市| 库尔勒市| 宁陵县| 瑞丽市| 拉萨市| 开阳县| 毕节市| 双桥区| 台山市| 宝山区| 石景山区| 汉沽区| 两当县| 共和县| 耒阳市| 本溪| 石渠县| 望江县| 佳木斯市| 玛纳斯县| 汕头市| 鄂托克旗| 墨竹工卡县| 汨罗市| 巴楚县| 黄石市| 共和县| 罗城| 靖州| 吕梁市| 辛集市| 阿拉善左旗| 南丰县|