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

    原文 : Stacktrace improvements in .NET Core 2.1 作者 : Ben Adams 译者 : 张很水 . NET Core 2.1 现在具有可读的异步堆栈信息!使 ...

  2. Not Found The requested URL / was not found on this server.

    http://www.wanysys.cc/coding/php/800.html 今天在做本地PHP项目的时候,想把之前wampserver的本地虚拟服务器环境访问方式改为本地localhost访问 ...

  3. 达尔稳usb转RJ45的接口转换器(usb2.0接口)在ubuntu16.04中驱动(r8152)编译安装与使用

    淘宝买了usb转RJ45的接口转换器:https://detail.tmall.com/item.htm?id=524808012954&ali_refid=a3_430582_1006:11 ...

  4. ng机器学习视频笔记(十六) ——从图像处理谈机器学习项目流程

    ng机器学习视频笔记(十六) --从图像处理谈机器学习项目流程 (转载请附上本文链接--linhxx) 一.概述 这里简单讨论图像处理的机器学习过程,主要讨论的是机器学习的项目流程.采用的业务示例是O ...

  5. 浅谈TreeMap以及在java中的使用

    treemap结构是红黑树 1.先介绍一下平衡二叉树 其特点是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.也就是说该二叉树的任何一个子节点,其左右子树的高度 ...

  6. django xadmin 集成DjangoUeditor富文本编辑器

    本文档记录自己的学习历程! 介绍 Ueditor HTML编辑器是百度开源的在线HTML编辑器,功能非常强大 额外功能 解决图片视频等无法上传显示问题 Ueditor下载地址 https://gith ...

  7. shell获取字符串长度

    方法1: 使用wc -L命令 wc -L可以获取到当前行的长度,因此对于单独行的字符串可以用这个简单的方法获取,另外wc -l则是获取当前字符串内容的行数. 代码如下: echo "abc& ...

  8. MySQL数据库中实现对中文字段按照首字字母排序

    转载自网络! 1. 在MySQL中,我们经常会对一个字段进行排序查询,但进行中文排序和查找的时候,对汉字的排序和查找结果往往都是错误的. 这种情况在MySQL的很多版本中都存在. 如果这个问题不解决, ...

  9. C#基础拾遗系列之一:先看懂IL代码

    一.前言 首先,想说说为什么要写这样系列的文章,有时候在和同事朋友聊天的时候,经常会听到这样的话题: (1)在这家公司没什么长进,代码太烂,学不到东西.(你有没有想想框架为什么这样写,代码还可以怎么去 ...

  10. C#小笔记:单例模式

    双重锁定: public class Singleton { private static Singleton instance; private static readonly object syn ...