最近项目要实现一个消息推送的功能,主要就是发送站内信或者系统主动推送消息给当前在线的用户。每次的消息内容保存数据库,方便用户下次登录后也能看到。如果当前用户在线,收到站内信就主动弹出提示。一开始想到的是前台定时轮询通过ajax查询是否有未读消息。但是这种对系统压力太大。然后网上查询dwr可以主动实时推送消息。现把实现代码贴出来,方便以后使用。

web.xml加入如下配置

<!-- dwr 实时推送  start-->
<servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>org.directwebremoting.spring.DwrSpringServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/dwr.xml</param-value>
</init-param>
<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>
<init-param>
<param-name>classes</param-name>
<param-value>java.lang.Object</param-value>
</init-param>
<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>3000</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>WARN</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping> <!-- dwr 实时推送 end -->

web.xml同级目录下新建dwr.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd">
<dwr> <!-- dwr 实时推送 end-->
<create creator="new" javascript="MessagePush">
<param name="class" value="com.xsw.dwrMsg.service.MessagePush"/>
</create>
<create creator="new" javascript="TestPush">
<param name="class" value="com.xsw.dwrMsg.service.TestPush"/>
</create>
<!-- dwr 实时推送 end-->
</allow>
</dwr>

MessagePush类

/**
* 版权所有(C) 2016 xsw
* @author xsw
* @date 2017-6-23 下午05:38:43
*/
package com.xsw.dwrMsg.service; import javax.servlet.ServletException; import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContextFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* @ClassName: MessagePush
* @Description: TODO()
* @author xsw
* @date 2017-6-23 下午05:38:43
*
*/ public class MessagePush {
private static Logger logger = LoggerFactory.getLogger(MessagePush.class);
public void onPageLoad(String userId) {
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
scriptSession.setAttribute(userId, userId);
DwrScriptSessionManagerUtil dwrScriptSessionManagerUtil = new DwrScriptSessionManagerUtil();
try {
dwrScriptSessionManagerUtil.init(); logger.info("["+userId+"]初始化,登录到推送的页面,站内信发送页面");
} catch (ServletException e) {
e.printStackTrace();
}
}
}

DwrScriptSessionManagerUtil工具类

/**
* 版权所有(C) 2016 xsw
* @author xsw
* @date 2017-6-26 下午06:31:46
*/
package com.xsw.dwrMsg.service;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession; import org.directwebremoting.Container;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.ylink.eu.base.web.EUWebUtil; /**
* @ClassName: DwrScriptSessionManagerUtil
* @Description: TODO()
* @author xsw
* @date 2017-6-26 下午06:31:46
*
*/ public class DwrScriptSessionManagerUtil extends DwrServlet{ private static final long serialVersionUID = -7504612622407420071L;
private static Logger logger = LoggerFactory.getLogger(DwrScriptSessionManagerUtil.class);
public void init()throws ServletException { 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 =EUWebUtil.getUserContext().getAccountName();
logger.info("a ScriptSession is created!["+userId+"]");
ev.getSession().setAttribute("userId", userId);
}
public void sessionDestroyed(ScriptSessionEvent ev) {
logger.info("a ScriptSession is distroyed");
}
};
manager.addScriptSessionListener(listener);
}
}

TestPush类

/**
* 版权所有(C) 2016 xsw
* @author xsw
* @date 2017-6-26 下午05:42:51
*/
package com.xsw.dwrMsg.service; import java.util.Collection; import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* @ClassName: TestPush
* @Description: TODO()
* @author xsw
* @date 2017-6-26 下午05:42:51
*
*/ public class TestPush {
private static Logger logger = LoggerFactory.getLogger(TestPush.class);
public void sendMessageAuto(String userid, String message){
logger.info("发送消息["+message+"]给["+userid+"]");
final String userId = userid;
final String autoMessage = message;
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.appendCall("showMessage", autoMessage); Collection<ScriptSession> sessions = Browser .getTargetSessions(); for (ScriptSession scriptSession : sessions){
scriptSession.addScript(script);
}
}
});
}
}

引入JavaScript文件,具体如下:

<script type="text/javascript" src="<%=basepath%>dwr/engine.js"></script>
<script type="text/javascript" src="<%=basepath%>dwr/util.js"></script>
<script type="text/javascript" src="<%=basepath%>dwr/interface/MessagePush.js"></script>

接收消息html页面具体内容代码如下:

<%@ 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>DWR DEMO</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">
</head>
<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/MessagePush.js"></script> <script type="text/javascript">
//通过该方法与后台交互,确保推送时能找到指定用户
function onPageLoad(){
var userId = '${userinfo.userId}';
MessagePush.onPageLoad(userId);
}
//推送信息
function showMessage(autoMessage){
alert(autoMessage);
}
</script>
<body onload="onPageLoad();dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);;">
This is my DWR DEOM page. <hr>
<br>
<div id="DemoDiv">demo</div>
</body>
</html>

发送消息html页面具体内容代码如下:

<%@ 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 'MyJsp.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">
<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/TestPush.js'></script> <script type="text/javascript"> function testPush() {
var msg = document.getElementById("msgId").value;
TestPush.sendMessageAuto(msg,"www.xiongge.club"); }
</script>
</head> <body>
id值: <input type="text" name="msgId" id="msgId" /> <br />
<input type="button" value="Send" onclick="testPush()" />
</body>
</html>

以上基本完成一个实时推送的功能。同时登陆用户A和B到系统,在A页面发送消息给B,B会alert出A发送的消息。以上代码仅供参考,优化扩展的方式有很多,欢迎交流。

原文地址http://www.xiongge.club/1239.html

dwr3+spring实现消息实时推送的更多相关文章

  1. 基于HTTP协议之WEB消息实时推送技术原理及实现

    很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...

  2. WebSocket实现站内消息实时推送

    关于WebSocket WebSocket是HTML5 开始提供的一种在单个TCP连接上进行全双工通讯的协议.什么是全双工?就是在同一时间可以发送和接收消息,实现双向通信,比如打电话.WebSocke ...

  3. 利用socket.io实现消息实时推送

    最近在写的项目中存在着社交模块,需要实现这样的一个功能:当发生了用户被点赞.评论.关注等操作时,需要由服务器向用户实时地推送一条消息.最终完成的项目地址为:socket-message-push,这里 ...

  4. Asp.net SignalR 实现服务端消息实时推送到所有Web端

    ASP .NET SignalR是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.实际上 Asp.net SignalR 2 实现 服务端消息推送到Web端, 更加 ...

  5. 基于swoole+Redis的消息实时推送通知

    swoole+Redis将实时数据的推送 一 实现功能 设计师订单如果设计师未抢单,超时(5分钟)设计订单时时给设计师派送, 设计师公众号中收到派单信息 设计发布者收到派单成功信息 环境 centos ...

  6. php 消息实时推送(反ajax推送)

    入口文件index.html <!DOCTYPE HTML> <html> <head> <title>反ajax推送</title> &l ...

  7. Channels集成到Django消息实时推送

    channel架构图 InterFace Server:负责对协议进行解析,将不同的协议分发到不同的Channel Channel Layer:频道层,可以是一个FIFO队列,通常使用Redis Dj ...

  8. nodejs+socketio+redis实现前端消息实时推送

    1. 后端部分 发送redis消息 可以参考此篇实现(直接使用Jedis即可) http://www.cnblogs.com/binyue/p/4763352.html 2.后端部分: 接收redis ...

  9. spring boot 集成 websocket 实现消息主动推送

    spring boot 集成 websocket 实现消息主动 前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单 ...

随机推荐

  1. flying中的AOP和IOC

    注入属性:private synchronized void injectReferenceServices() { if(this.injectReferenceServicesInitialize ...

  2. js promise看这篇就够了

    一.背景 大家都知道nodejs很快,为什么会这么快呢,原因就是node采用异步回调的方式来处理需要等待的事件,使得代码会继续往下执行不用在某个地方等待着.但是也有一个不好的地方,当我们有很多回调的时 ...

  3. Python self学习

    最开始学习Python时,用的IDE是IDEL,看的教程是<简明Python教程>,强烈推荐一下,讲得还是很不错的,适合新手学习 http://www.kuqin.com/abyteofp ...

  4. Chrome中xpath表达式巧妙获取

    对于xpath语法不熟悉,或者要快速匹配出xpath的小伙伴来说这种方式是最快捷的了. 步骤如下: 1.打开chrome 2.ctrl + shift + c 个人比较喜欢用快捷键,不喜欢用快捷键的就 ...

  5. python3中,os.path模块下常用的用法总结

    abspath basename dirname exists getatime getctime getmtime getsize isabs isdir isfile islink ismount ...

  6. c#实现Word转换PNG图片

    由于项目需要,经过一些大神的指导以及github,stackOverflow找资料,写了个这么个程序. 主要是因为word文档有特殊字体,特殊字体处理就要用到EnhMetaFileBits,即获取一页 ...

  7. ABP 数据迁移

    我主要是在项目部署的时候.当添加一个租户的时候.那么租户是有一个单独的数据库.而我的并没有用多租户单数据库. 因此我的模块里面有一个领域事件 当租户添加时将生前表生成到对应的数据库中.如果那位网友有更 ...

  8. linux中sed在指定字符前后添加内容

      假设文档内容如下: [root@localhost ~]# cat /tmp/input.txt null 000011112222 test 要求:在1111之前添加AAA,方法如下: sed ...

  9. bzoj 4591: [Shoi2015]超能粒子炮·改 [lucas定理]

    4591: [Shoi2015]超能粒子炮·改 题意:多组询问,求 \[ S(n, k) = \sum_{i=0}^n \binom{n}{i} \mod 2333,\ k \le n \le 10^ ...

  10. Matplotlib学习笔记(一)

    原   matplotlib学习笔记 参考:Python数据科学入门教程 Python3.6.1 jupyter notebook .caret, .dropup > .btn > .ca ...