DWR3.0推送技術實現QQ即時通信功能(2)

上節實現了Ajax功能,本節實現服務器的推送。

首先了解一下什麼是服務器推送技術和DWR的推送方式。

1.服務器推送技術和DWR的推送方式

傳統模式的 Web 系統以客戶端發出請求、服務器端響應的方式工作,服務端不能主動發送請求(消息)給客戶端。
這種方式並不能滿足很多現實應用的需求,譬如:
        監控系統:後臺硬件熱插拔、LED、溫度、電壓發生變化;
        即時通信系統:其它用戶登錄、發送信息;
        即時報價系統:後臺數據庫內容發生變化;

  這些應用都需要服務器能實時地將更新的信息傳送到客戶端,而無須客戶端發出請求。“服務器推”技術在現實應用中有一些解決方案,這些解決方案大致可以分爲兩類:
          一類需要在瀏覽器端安裝插件,基於套接口(Socket)傳送信息,或是使用 RMI、CORBA 進行遠程調用;而另一類則無須瀏覽器安裝任何插件、基於 HTTP 長連接。

  而基於客戶端套接口的“服務器推”技術大體可以分爲:

    1.傳統輪詢:在 Web 早期,這一點常使用 meta 刷新實現。這將自動指示瀏覽器在指定秒數之後重新裝載頁面,從而支持簡陋的輪詢( polling )。例如在 HTML 文件中加入 <META HTTP-RQUIV="Refresh" CONTENT=12> ,實際上就是 HTTP 頭標告知瀏覽器每 12 秒更新一次文檔。

          優點:不需要服務器端配置

          缺點:用戶體驗度差

             對服務器的壓力很大,帶寬流失嚴重

    2.ajax輪詢:Ajax 隔一段時間(通常使用 JavaScript 的 setTimeout 函數)就去服務器查詢是否有改變,從而進行增量式的更新。但是間隔多長時間去查詢成了問題,因爲性能和即時性造成了嚴重的反比關係。間隔太短,連續不斷的請求會沖垮服務器,間隔太長,務器上的新數據就需要越多的時間才能到達客戶機。

          優點:不需要太多的服務器端配置

              降低了帶寬的負荷(因爲返回的不是完整的頁面)

          缺點:對服務器的壓力並沒有減少

             實時性差,有一定的延遲

          應用:這種技術很常見,很多webmail應用程序就是通過這種技術在電子郵件到達時顯示電子郵件的。

    3.comet:Comet 方式通俗的說就是一種長連接機制 (long lived http) 。同樣是由 Browser 端主動發起請求,但是 Server 端以一種似乎非常慢的響應方式給出回答。這樣在這個期間內,服務器端可以使用同一個 connection 把要更新的數據主動發送給 Browser 。因此請求可能等待較長的時間,期間沒有任何數據返回,但是一旦有了新的數據,它將立即被髮送到客戶機。Comet 又有很多種實現方式,但是總的來說對 Server 端的負載都會有增加 . 雖然對於單位操作來說,每次只需要建議一次 connection, 但是由於 connection 是保持較長時間的 , 對於 server 端的資源的佔用要有所增加。

          優點:實時性好(消息延時小);性能好(能支持大量用戶)         

          缺點:長期佔用連接,喪失了無狀態高併發的特點。

          應用:股票系統。實時通訊。

    4.flash xml socket:這種方案實現的基礎是:一、 Flash 提供了 XMLSocket 類。二、 JavaScript 和 Flash 的緊密結合:在 JavaScript 可以直接調用 Flash 程序提供的接口。

          優點:實時性好(消息延時小);性能好(能支持大量用戶)         

          缺點:因爲 XMLSocket 沒有 HTTP 隧道功能, XMLSocket 類不能自動穿過防火牆;

             因爲是使用套接口,需要設置一個通信端口,防火牆、代理服務器也可能對非 HTTP 通道端口進行限制;

          應用:網絡聊天室,網絡互動遊戲。

    5.java appet:在客戶端使用 Java Applet ,通過 java.net.Socket 或 java.net.DatagramSocket 或 java.net.MulticastSocket 建立與服務器端的套接口連接,從而實現 “ 服務器推送 ” 。

DWR採用的是長連接機制。

1、長連接技術通過客戶端發出請求獲取服務器端數據的方式通常稱爲"拉"技術,很形象說明客戶端在拉取服務器端數據,而有時候需要服務器端主動向客戶端"推"數據,比如監測聊天上線人數主動向上線發送消息,後臺數據庫發生變化是主動更新所有客戶端展示。

2、Reverse Ajax實現服務器推技術DWR2.x的推技術也叫DWR Reverse Ajax(逆向Ajax)主要是在BS架構中,從服務器端向多個瀏覽器主動推數據的一種技術。DWR的逆向Ajax主要包括兩種模式:主動模式和被動模式。其中主動模式包括polling和comet兩種,被動模式只有piggyback這一種:

(1)piggyback方式,是默認的方式。如果後臺有什麼內容需要推送到前臺,是要等到那個頁面進行下一次ajax請求的時候,將需要推送的內容附加在該次請求之後,傳回到頁面。只有等到下次請求頁面主動發起了,中間的變化內容才傳遞迴頁面。

(2)comet方式當服務端建立和瀏覽器的連接,將頁面內容發送到瀏覽器之後,對應的連接並不關閉,只是暫時掛起。如果後面有什麼新的內容需要推送到客戶端的時候直接通過前面掛起的連接再次傳送數據。服務器所能提供的連接數目是一定的,在大量的掛起的連接沒有關閉的情況下,可能造成新的連接請求不能接入,從而影響到服務質量。

(3)polling方式由瀏覽器定時向服務端發送ajax請求,詢問後臺是否有什麼內容需要推送,有的話就會由服務端返回推送內容。這種方式和我們直接在頁面通過定時器發送ajax請求,然後查詢後臺是否有變化內容的實現是類似的。


 2.ScriptSession的生命週期
客戶端每次請求(刷新)都會生成一個新的ScriptSession,當客戶端請求時或者客戶端退出時將會銷燬ScriptSession。

通過ScriptSession我們可以得到客戶端(瀏覽器)的腳本執行權。即我們可以直接調用瀏覽器的js代碼。

本節實現的基本功能:
在上節(DWR3.0推送技術實現QQ即時通信功能(1))的代碼基礎上修改,實現將index.jsp輸入框中的推送文本顯示在其它打開的jsp頁面上
1.修改MessagePush中的sendMessage方法:
package com.DWR.dwr;

import java.util.Collection;

import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;

public class MessagePush {
	public void sendMessage(final String content){
		Runnable run = new Runnable(){
			ScriptBuffer script = new ScriptBuffer();
			public void run(){
				//設置要調用的 js及參數
				script.appendCall("showMessage",content);
				//得到所有ScriptSession   
				Collection<ScriptSession> sessions = Browser.getTargetSessions();
				for(ScriptSession session :sessions){
					session.addScript(script);
				}
			}
		};
		//執行推送
		Browser.withAllSessions(run);
	}
}

2.新建receive.jsp用來接收來自服務器的消息:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'receive.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
	<script src="jquery-1.7.js"></script>
	<script type= "text/javascript" src ="dwr/util.js"></script>     
     <script type="text/javascript" src= "dwr/engine.js"></script >   
     <script type="text/javascript" src= "dwr/interface/messagePush.js" ></script>  
	<script>
			//這個方法用來啓動該頁面的ReverseAjax功能 
			dwr.engine.setActiveReverseAjax(true);
			//設置在頁面關閉時,通知服務端銷燬會話 
			dwr.engine.setNotifyServerOnPageUnload(true);
			//這個函數是提供給後臺推送的時候 調用的
		
		function showMessage(content){
				$('#getMessage').append(content);
		};
	</script>
  </head>
  
  <body>
    	<div id="getMessage" style="padding:100px;border:1px solid #F00;">
    	
    		<ul></ul>
    	</div>
  </body>
</html>

3.web.xml加入activeReserveAjax功能
 <init-param>
            <param-name>activeReverseAjaxEnabled</param-name>
            <param-value>true</param-value>
 </init-param>

測試:
先打開receive.jsp,後打開index.jsp輸入文本後發送,效果如圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章