最近项目要实现一个消息推送的功能,主要就是发送站内信或者系统主动推送消息给当前在线的用户。每次的消息内容保存数据库,方便用户下次登录后也能看到。如果当前用户在线,收到站内信就主动弹出提示。一开始想到的是前台定时轮询通过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. 解决Flink输出日志中时间比当前时间晚8个小时的问题

    Flink安装在CentOS7上,默认时间是UTC时间,查看Flink日志,发现输出时间比当前时间晚8个小时. 通过如下命令,调整成北京时间 cp /usr/share/zoneinfo/Asia/S ...

  2. XML (二)

    1 SAX 在使用DOM解析XML文档的时候,需要读取整个XML文档,在内存中构架代表整个DOM树的Document对象,从而再对XML文档进行操作.此种情况下,如果XML文档特别大,就会消耗计算机的 ...

  3. 合理使用软引用和弱引用,提升JVM内存使用性能

    在项目运行时,OOM异常是比较处理的,因为从日志看出的发生异常的代码点可能仅仅是最后一根稻草,从中可能未必能发现OOM的原因,而且OOM未必是固定重现的. 上医治未病,与其等OOM问题发生时再通过看日 ...

  4. nodejs爬虫笔记(五)---利用nightmare模拟点击下一页

    目标 以腾讯滚动新闻为例,利用nightmare模拟点击下一页,爬取所有页面的信息.首先得感谢node社区godghdai的帮助,开始接触不太熟悉nightmare,感觉很高大上,自己写代码的时候问题 ...

  5. Struts2中拦截器的使用与配置

    一,拦截器是什么? 拦截器是在Action执行之前和之后执行的代码,是一个类似于过滤器的类: 二,拦截器的作用 拦截器拦截Action的请求,在Action之前或之后实现某项功能: 三,拦截器的特点 ...

  6. Databricks缓存提升Spark性能--为什么NVMe固态硬盘能够提升10倍缓存性能(原创)

    我们兴奋的宣布Databricks缓存的通用可用性,作为统一分析平台一部分的 Databricks 运行时特性,它可以将Spark工作负载的扫描速度提升10倍,并且这种改变无需任何代码修改. 1.在本 ...

  7. [SF] Symfony 组件 BrowserKit 原理

    直接看下面的注释中针对每一个文件的作用说明. <?php /** * BrowserKit - Make internal requests to your application. * * I ...

  8. [JavaScript]自执行函数

    最近在接触mui的时候,遇到了一段代码: (function($, doc) { $.init({ statusBarBackground: '#f7f7f7' }); $.plusReady(fun ...

  9. java中的二叉树排序问题

    原创:转载请注明出处 目的:想用java实现二叉树排序算法 思想:利用java中面向对象的思想,即: Tree:类 树根Tree:root //static所属于每一个Tree 左节点Tree:lef ...

  10. 禁掉或启用firefox 的 javascript 脚本

    老版本的firefox可以直接在“选项”页设置启用或禁用javascript 脚本 新版的Firefox中,我找了半天,没有找到,看来是没法直接设置了 于是在 地址栏键入 about:config 搜 ...