利用dwr框架來實現“服務推”技術的方法



利用dwr框架來實現“服務推”技術的方法:

n 官網上主要有三種方法:

1.Polling:輪詢是解決此問題最常見的方法。瀏覽器不斷對服務端發起一個請求,來檢測頁面(數據)是否有更新。舉個例子:就像是一個幾歲的小孩跟在汽車後面不斷的喊“我們在這裏”。

2.Comet:通過這種方法服務器可以緩慢的響應客戶端的請求,持續響應有服務器管理的任務表。更多信息參考:

Comet百度百科

· Alex Russell's original post coining the term

· The Wikipedia article on Comet

· Comet Daily, a blog with regular posts on the subject

3.Piggyback:採用這種方法,如果有數據更新,服務端等待客戶端的連接後發送數據。

三種方法比較:

Polling方法容易實現,但也容易增加服務器負擔。和Comet相比,comet不會使用太多的服務器資源,同時,低延遲,因爲不需要等待瀏覽器的下次連接。Polling和comet都要求額外的網絡連接,即長連接,所以piggyback是低負載的最佳方法,但延遲高。

 

n 如何使用dwr框架

(1)準備相關jar,包括dwr.jar,commons-logging.jar,並將它們放到/WEB-INF/lib目錄下;如果使用maven,則不需求添加jar,直接在pom.xml文件中的<dependencies>標籤中添加如下內容:

<!--使用dwrjar包,必須添加的兩個jar包,dwr.jar和commons-logging.jar-->
<dependency>
    <groupId>org.directwebremoting</groupId>
    <artifactId>dwr</artifactId>
    <version>2.0.10</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

(2)映射文件

a)映射文件的配置,將如下代碼添加到應用的web.xml文件中

<servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

b)映射文件的添加,文件名爲dwr.xml的文件放到與web.xml文件同一級目錄,其dwr.xml文件內容如下所示:注意:這個文件是和你的Java Bean一起寫的。

<!DOCTYPE dwr PUBLIC    "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"    "http://getahead.org/dwr/dwr30.dtd"> <dwr>  <allow>    <create creator="new" javascript="JDate">      <param name="class" value="java.util.Date"/>    </create>    <create creator="new" javascript="Demo">      <param name="class" value="your.java.Bean"/>    </create>  </allow></dwr>

(3)測試DWR驅動,剛纔添加的類是否起作用,訪問http://localhost:8080/[項目名稱]/dwr/得到剛纔添加的類(項目名稱不一定非得添加,根據你自己項目的部署情況)

結果如下圖所示:

 

點擊超鏈接進去某個類並進行方法的測試:

 

2

如果有參數輸入參數並直接點擊Execute即可,原理是通過js來調用Java代碼。

(4)以上步驟基本完成,但是boss或客戶肯定看不懂,那麼怎麼轉換成客戶看的懂的東西?

a)新建一個HTMl或JSP文件,如index.jsp

將圖2中的js文件即以下內容添加到index.jsp中,如下所示,注意文件路徑問題,自己把握。

<script type='text/javascript' src='/dwr/interface/Hello.js'></script><script type='text/javascript' src='/dwr/engine.js'></script>

<script type='text/javascript' src='/dwr/util.js'></script>

b)寫js代碼通過js來調用Java代碼:

如下所示:

<script type="text/javascript">

function hello(){

var user=$('user').value;

Hello.sayHello(user,callback);

}

function callback(msg){

dwr.util.setValue('result',msg);

}

</script>

<body>

<input id="user" type="text">

<input type="button" value="打招呼" onclick="hello()">

<div id="result"></div>

</body>

其中user是sayHello()方法的參數,callback是回調函數,如果java中的方法沒有返回參數就不需要。

其實系統自動生成的Execute方法就相當於此處的hello()方法

n 如何使用DWR實現Reverse Ajax(Server Push),以服務端的文本數據的變化從而推送到客戶端爲例來介紹。

0.1)通用配置,無論使用哪種方法都要在web.xml文件中添加如下配置:該配置意思是激活反Ajax

<servlet>  <servlet-name>dwr-invoker</servlet-name>  <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>  <init-param>    <param-name>activeReverseAjaxEnabled</param-name>    <param-value>true</param-value>  </init-param></servlet>

0.2)在web網頁中激活反Ajax請求,在頁面中添加如下代碼即可:

dwr.engine.setActiveReverseAjax(true);

  (1)新建一個SendData類並在dwr.xml文件中配置

    a)SendData類中代碼的主要思想:實現思路:在類的構造函數中構造一個任務定時器,利用任務定時器按時執行主任務(例如.顯示數據到頁面)

     主要代碼如下所示:

public SendData() {
    //定義一個執行任務的線程池,池中線程爲1
    executor=new ScheduledThreadPoolExecutor(1);
    //60s執行一次
    executor.scheduleAtFixedRate(this,1,60, TimeUnit.SECONDS);
}

@Override
public void run() {
    //執行主任務:及時向客戶端發送更新後的數據
    sendDataTimely();
}
public void sendDataTimely() {
    //準備數據
    String filePath = "D:/text.txt";
    BufferedReader reader = null;
    final StringBuffer sb = new StringBuffer();
    try {
        reader = new BufferedReader(new InputStreamReader(
                new FileInputStream(filePath), "UTF-8"));

        String tempString = null;

        while ((tempString = reader.readLine()) != null) {
            sb.append(tempString + "\n\r");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //顯示數據  將數據發送到根目錄下的showdata.html文件中
    String page = ServerContextFactory.get().getContextPath()
            + "/showdata.html";
    Browser.withPage(page, new Runnable() {
        public void run() {
            //將內容顯示到showdata頁面中的“id=content”元素中
            Util.setValue("content"sb.toString());
        }
    });
}

 

  (2)新建一個showdata.html頁面,主要代碼如下:

<script>
    window.onload function () {
        dwr.engine.setActiveReverseAjax(true);
        dwr.engine.setErrorHandler(errorHandler);
        dwr.engine.setNotifyServerOnPageUnload(true);
        SendData.addAttributeToScriptSession();
    }
    function errorHandler(message, ex) {
        dwr.util
                .setValue(
                "error",
                "<font color='red'>Cannot connect to server. Initializing retry logic.</font>",
                {
                    escapeHtmlfalse
                });
        setTimeout(function () {
            dwr.util.setValue("error""");
        }, 5000)
    }
</script>

實現的效果是:如果D:/text.txt下的文本發生變化,會在1min中後同步更新到客戶端中。

源代碼地址如下:

Githttps://github.com/weichenjushi/dwr.helloworld.git

Svnhttps://github.com/weichenjushi/dwr.helloworld

 

n 注意事項:

1)如果使用DWR3的話,可能會彈框

 

解決辦法:將以下代碼添加到配置的DWRServlet的配置文件中:

 <init-param>
             <param-name>crossDomainSessionSecurity</param-name>
             <param-value>false</param-value>
      </init-param>
      <init-param>
            <param-name>allowScriptTagRemoting</param-name>
            <param-value>true</param-value>
  </init-param>

 

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