首页 > 其他 > 详细

DWR实现精确推送

时间:2014-04-07 15:50:33      阅读:402      评论:0      收藏:0      [点我收藏+]

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

bubuko.com,布布扣
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);
                    }
                }
            }
        });
    }
}
bubuko.com,布布扣

 

二、前台改造

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

bubuko.com,布布扣
<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>
bubuko.com,布布扣

 

 

三、运行效果

 

打开一个name为a的窗口,两个name为b的窗口,a向b发送的消息两个b窗口都能收到推送,而b发给a的消息,只有a窗口接收到了推送。

 bubuko.com,布布扣

控制台显示如下:

bubuko.com,布布扣

可以维护一个在线用户的Map来控制用户的唯一性,这需要定义一个简单的协议,以区分消息是通知用户下线还是发送的消息,稍后我会写一篇博客来实现这个Demo。

DWR实现精确推送,布布扣,bubuko.com

DWR实现精确推送

原文:http://www.cnblogs.com/nianzecong/p/3647399.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!