DWR實現精確推送


DWR會在頁面鏈接后台時,創建一個對應的ScriptSession對象,通過調用對應ScriptSession的scriptSession.addScript(script);方法來進行消息推送。

可以在相應的scriptSession中添加“name“屬性來區分推送的目標,實現精確推送。

org.directwebremoting.Browser :http://directwebremoting.org/dwr/javadoc/org/directwebremoting/Browser.html

以下代碼是在 DWR實現消息廣播 的基礎上進行改造的。

 

一、后台改造

1.在后台代碼中增加onPageLoad方法,在scriptSession中增加推送的唯一標識。

2.利用ScriptSessionFilter對所有的scriptSession進行過濾。

3.向符合條件的頁面進行推送

com.test.Message.java

package com.test;

import java.util.Collection;

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

public class Message {
    // 載入頁面時調用,傳入name值作為推送的標識
    public void onPageLoad(String name) {
        ScriptSession session = WebContextFactory.get().getScriptSession();
        session.setAttribute("name", name);
    }
    public void addMessage(String userid, String message) {
        final String userId = userid;
        final String autoMessage = message;
        ScriptSession session = WebContextFactory.get().getScriptSession();
        final String from = session.getAttribute("name").toString();
        System.out.println("From: " + from + ", To: " + userid + ", Msg: "
                + message);
        // 通過ScriptSessionFilter篩選符合條件的ScriptSession
        Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
            // 實現match方法,條件為真為篩選出來的session
            public boolean match(ScriptSession session) {
                String name = session.getAttribute("name").toString();
                return name == null ? false : userId.equals(name);
            }
        }, new Runnable() {
            private ScriptBuffer script = new ScriptBuffer();
            public void run() {
                // 設定前台接受消息的方法和參數
                script.appendCall("receiveMessages", autoMessage);
                Collection<ScriptSession> sessions = Browser
                        .getTargetSessions();
                // 向所有符合條件的頁面推送消息
                for (ScriptSession scriptSession : sessions) {
                    if (scriptSession.getAttribute("name").equals(userId)) {
                        scriptSession.addScript(script);
                    }
                }
            }
        });
    }
}

 

二、前台改造

1.引入了jquery,方便dom操作,由DwrServlet生成的 util.js 也具有dom操作功能。

2.在頁面加載完畢之后,做了三件事:

2.1.dwr.engine.setActiveReverseAjax(true),開啟逆向Ajax模式,在 DWR實現消息廣播 例子中,寫在body標簽的onload方法中

2.2.dwr.engine.setNotifyServerOnPageUnload(true),這個方法設置DWR在頁面關閉時銷毀后台無效的ScriptSession,也可以使用setNotifyServerOnPageUnload(true, true)方法異步通知后台該ScriptSession無效。如果設置為false或者通知后台失敗,將會采用延時銷毀策略,以保證后台的ScriptSession都是有效的。

2.3.調用后台的onPageLoad方法,設置url中的name屬性為推送唯一標識

在我本機的訪問地址為 http://localhost:8080/Dwr-comet/index.jsp?name=a

index.jsp

<html>
<head>
<title>DWR - cometDemo</title>
<script type="text/javascript" src="./dwr/engine.js"></script>
<script type="text/javascript" src="./dwr/util.js"></script>
<script type="text/javascript" src="./dwr/interface/Message.js"></script>
<script type="text/javascript" src="js/jquery-1.4.2.js"></script>
<script type="text/javascript">
    var chatlog = "";
    
    function sendMessage() {
        var message = $("#message").val();
        var user = $("#user").val();
        // 通過代理調用后台的addMessage方法發送消息
        Message.addMessage(user, message);
    }
    
    // 前台接受消息的方法,由后台調用 
    function receiveMessages(messages) {
        var lastMessage =  messages;
        chatlog = "<p>" + lastMessage + "</p>" + chatlog;
        $("#list").html(chatlog);
    }
    
    //讀取name值作為推送的唯一標示
    function onPageLoad(){
        // 獲取URL中的name屬性為唯一標識符
        var userId = getQueryString("name");
        $("#myName").html(userId);
        // 通過代理,傳入區別本頁面的唯一標識符
        Message.onPageLoad(userId);
     }

    //獲取url中的參數
    function getQueryString(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]); return null;
    }

    $(document).ready(function(){
        dwr.engine.setActiveReverseAjax(true);// 開啟逆向Ajax,也可寫在body標簽的onload方法中
        dwr.engine.setNotifyServerOnPageUnload(true);
        onPageLoad();
        }); 

</script>
</head>
<body>
    My name is:<span id="myName" style="color:red"></span><br/>
    To:<br/>
    <input id="user" type="text" /><br/>
    input message:<br/>
    <input id="message" type="text" value="hey" />
    <input type="button" value="send" onclick="sendMessage()" />
    <br>
    <div id="list"></div>
</body>
</html>

 

 

三、運行效果

 

打開一個name為a的窗口,兩個name為b的窗口,a向b發送的消息兩個b窗口都能收到推送,而b發給a的消息,只有a窗口接收到了推送。

 

控制台顯示如下:

可以維護一個在線用戶的Map來控制用戶的唯一性,這需要定義一個簡單的協議,以區分消息是通知用戶下線還是發送的消息,稍后我會寫一篇博客來實現這個Demo。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM