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

    easyUI中点击datagrid的排序有两种,一种是本地的,一种是服务器的.本地的只能排序当前页,而服务器的可以对全部页进行排序.这里主要是分享下服务器排序. 1.为datagrid添加属性remo ...

  2. SQL Server ——动态SQL

    EXECUTE 执行 Transact-SQL 批中的命令字符串.字符串或执行下列模块之一:系统存储过程.用户定义存储过程.标量值用户定义函数或扩展存储过程.SQL Server 2005 扩展了 E ...

  3. 定时任务schedule(spring boot )

    1. 定时任务实现方式:SpringBoot自带的Scheduled,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多,本文主要介绍. 执行方式:单线程(串行)多线程(并行) ...

  4. java枚举 用于声明持久化常量 和volley 请求头

    在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. public e ...

  5. Unity3d 基本设计开发 原则(提高代码可读性)

    参考:http://blog.csdn.net/qq_34134078/article/details/51780356 1.单一原则 即:明确类的定义.通俗来讲,让他们只做一件事,而不是多件事. 提 ...

  6. CSS继承、层叠和特殊性

    1.继承 (1)样式应用于某个特定的HTML标签元素,而且应用于其后代. (2)但某些标签不适用,如border: (3)例子:p{color:red;}设置了颜色 <p class=" ...

  7. mysql备份

    工具 mysql mysqldump 应用举例 导出 命令行下具体用法如下: mysqldump -u用戶名 -p密码 -d 数据库名 表名 脚本名; 1.导出数据库为dbname的表结构(其中用戶名 ...

  8. Django----模板层

    一.模板层:           python的模板:HTML代码+模板语法      模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签. import datetime t=dateti ...

  9. 如何学习java

    1.打牢基础 千里之行始于足下,只有牢固的基础才能走的更远,现在大公司越来越看中一个人的基础如何,他们看中的是你未来的发展潜力,有足够好的基础素养才能实现更多的可能. 2.多敲多练 说实话,光去看代码 ...

  10. selenium的使用技巧及集成到scrapy

    为了爬取拉钩,今天学习了selenum的使用技巧.   from scrapy.http import HtmlResponse   class JSPageMiddleware(object):   ...