DWR+Spring实现服务端消息推送

一、DWR介绍

DWR(Direct Web Remoting)可用于实现javascript直接调用java函数和后台直接调用页面javascript代码,后者可用作服务端推送消息到Web前端。

二、环境搭建

1.dwr-3.0.0-RELEASE.jar(在maven中央仓库下载)

2.spring-3.2.2.RELEASE

3.jdk1.7

三、dwr配置

1.在resources下创建dwr.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
    <allow>
        <!-- 建立JS对象,将目标对象的方法转换成JS对象的方法 -->
        <create javascript="dwrPush" creator="new">
            <param name="class" value="com.yudu.dwr.DwrPush"></param>
        </create>
        <!-- 指定针对于特定对象的转换器 -->
        <convert match="entity.*" converter="bean"></convert>
        <convert match="java.lang.Throwable" converter="bean">
            <param name="include" value="message"></param>
        </convert>
    </allow>
</dwr>

2.web.xml配置

<!-- 配置DWR前端控制器 -->
  <servlet>
      <servlet-name>dwrServlet</servlet-name>
      <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
      <!-- 指定配置文件 -->
      <init-param>
          <param-name>config</param-name>
          <!-- 如果有多个用","分开 -->
          <param-value>
              /WEB-INF/classes/dwr.xml                
          </param-value>
      </init-param>
      <init-param>
          <param-name>debug</param-name>
          <param-value>true</param-value>
      </init-param>
      <!-- 设置使用反向Ajax技术 -->
       <init-param>
        <param-name>activeReverseAjaxEnabled</param-name>
        <param-value>true</param-value>
       </init-param>
       <init-param>
        <param-name>
         initApplicationScopeCreatorsAtStartup
        </param-name>
        <param-value>true</param-value>
       </init-param>
       <init-param>
       <!--长连接只保持时间 -->
        <param-name>maxWaitAfterWrite</param-name>
        <param-value>60</param-value>
       </init-param>
  </servlet>

四、后端

package com.yudu.dwr;

import java.util.Collection;

import javax.servlet.http.HttpSession;

import org.directwebremoting.Browser;
import org.directwebremoting.Container;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.directwebremoting.extend.ScriptSessionManager;
import org.directwebremoting.servlet.DwrServlet;
import com.ccc.system.model.UserInfo;


public class DwrPush{

    public void onPageLoad(String userId){
        ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
        scriptSession.setAttribute(userId, userId);
        DwrScriptSessionManagerUtil  dssmu = new DwrScriptSessionManagerUtil();
        dssmu.init();
    }
    
    public void sendMsg(String userid,String org){
        final String userId = userid;
        final String msg = org;
        final String jsFunc = "receiveMsg";
        Browser.withAllSessionsFiltered(new ScriptSessionFilter(){
            public boolean match (ScriptSession session){
                if(session.getAttribute("userId") == null) return false;
                else {
                    return (session.getAttribute("userId")).equals(userId);
                }
            }
        }, new Runnable(){
            private ScriptBuffer script  = new ScriptBuffer();
            public void run(){
                script = script.appendScript(jsFunc+"(");
                script = script.appendData(msg);
                script = script.appendScript(")");
                Collection<ScriptSession> sessions = Browser.getTargetSessions();
                for(ScriptSession scriptSession : sessions){
                    scriptSession.addScript(script);
                }
            }
        });
    }
    class DwrScriptSessionManagerUtil extends DwrServlet{
        private static final long serialVersionUID = -7504612622407420071L;
        
        public void init(){
            Container container = ServerContextFactory.get().getContainer();
            ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);
            ScriptSessionListener listener = new ScriptSessionListener(){
              public void sessionCreated(ScriptSessionEvent ev) {
                     HttpSession session = WebContextFactory.get().getSession();
                     String userId =((UserInfo) session.getAttribute("userinfo")).getUserInfoId()+"";
                     ev.getSession().setAttribute("userId", userId);
              }
              public void sessionDestroyed(ScriptSessionEvent ev) {}
            };
            manager.addScriptSessionListener(listener);
        }
    }
}

五、前端
1.查看http://ip:port/program/dwr/

image.png

2.html

<script type='text/javascript' src='/traveloa/dwr/engine.js'></script>
<script type='text/javascript' src='/traveloa/dwr/interface/dwrPush.js'></script>
<script type='text/javascript' src='/traveloa/dwr/util.js'></script>
<script>
function init(){
    dwr.engine.setActiveReverseAjax(true);
    dwr.engine.setNotifyServerOnPageUnload(true);
    var userId='${userInfo.userInfoId}';
    dwrPush.onPageLoad(userId);
}
window.onload = init;
function send(msg){
    var userId='${userInfo.userInfoId}';
    dwrPush.sendMsg(userId,msg);
}
function receiveMsg(msg){
    alert(dwr.util.toDescriptiveString(msg));
}
</script>   
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容