Spring MVC+DWR3反向消息精准推送

版权声明:不存在一劳永逸的技术 只存在不断学习的人。本文为博主原创文章,未经博主允许不得转载。交流联系QQ:1120121072 https://blog.csdn.net/u013474568/article/details/85089804

Spring MVC+DWR3反向消息精准推送

简介

DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站。它可以允许在浏览器里的代码使用运行在WEB服务器上的JAVA方法,就像它就在浏览器里一样。

示例

[springMVC+dwr3 实现精确推送信息(2种方法)]:https://blog.csdn.net/threesan333/article/details/12502689
[三种推送方式]: https://blog.csdn.net/yxpjx/article/details/5004812
注意:DWR默认采用piggyback被动推送的推送方式,在Windows环境下能够即时接收;但在Linux环境中,并不生效。针对Linux下服务器不推送的情况需采用polling轮询推送

项目示例

需求介绍

公司有个功能叫做出入室管理,类似大厦进出登记一样,前台提供身份证识别机器,用户刷身份证登记之后(服务器自动查询该人员是否能够入室)如果存在入室清单中,前台浏览器界面自动弹出该人员入室登记信息,填写入室门禁卡号码之后将卡还有签字板提供入室人员签字,人员签字确认之后,由前台点击完成入室操作。

该功能需对接两个硬件厂商,分别是身份证读卡器以及签字板,对接过程的省略。直接说读取身份证之后自动弹出入室人员界面,这里需要运用服务器主动推送信息并打开页面。推送的框架有比较旧的DWR、GoEasy、WebSocket等。但由于项目框架版本低且不在支持的应用服务器之内,只能选择网上流传过时的DWR。

首先引入dwr jar包:

<!-- DWR -->
<dependency>
    <groupId>org.directwebremoting</groupId>
    <artifactId>dwr</artifactId>
    <version>3.0.2-RELEASE</version>
</dependency>

web.xml加入DWR配置

	<!-- 配置DWR的核心Servlet -->
	<servlet>
		<display-name>DWR Servlet</display-name>
		<!-- 指定DWR核心Servlet的名字 -->
		<servlet-name>dwr-invoker</servlet-name>
		<!-- 指定DWR核心Servlet的实现类 -->
		<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
		<!-- 指定DWR核心Servlet处于调试状态 -->
		<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>pollAndCometEnabled</param-name>  
		    <param-value>true</param-value>  
		  </init-param>  
		   <!-- 是能够从其他域请求true:开启; false:关闭 -->
		  <init-param>  
		    <param-name>crossDomainSessionSecurity</param-name>  
		    <param-value>true</param-value>  
		  </init-param> 
		  <!-- 允许远程调用js --> 
		  <init-param>  
		    <param-name>allowScriptTagRemoting</param-name>  
		    <param-value>true</param-value>  
		  </init-param>  
		  <!--  针对Linux下服务器不推送的情况。详见:https://blog.csdn.net/yxpjx/article/details/5004812 -->
		  <!-- 默认方式:piggyback(被动模式); -->
		 <init-param>
			<param-name>org.directwebremoting.extend.ScriptSessionManager</param-name>
			<param-value>com.ccssoft.rsas.bjflow.idcpersonentry.service.DwrScriptSessionManagerUtil</param-value>
		  </init-param>
		  <init-param>
			  <param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>
			  <param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>
          </init-param>
          <!-- 反转Ajax间隔:默认5毫秒,看源码所得。http://localhost:9090/dwr/call/plainpoll/ReverseAjax.dwr -->
          <!-- 
          <init-param>
			  <param-name>disconnectedTime</param-name>
			  <param-value>5000</param-value>
		</init-param>
		 -->
		  <load-on-startup>1</load-on-startup> 
	</servlet>

	<servlet-mapping>
		<servlet-name>dwr-invoker</servlet-name>
		<url-pattern>/dwr/*</url-pattern>
	</servlet-mapping>

WEB-INF下新建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>
	<allow>
	</allow>
</dwr>

创建类DwrScriptSessionManagerUtil

package com.ccssoft.rsas.bjflow.idcpersonentry.service;

import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.directwebremoting.impl.DefaultScriptSession;
import org.directwebremoting.impl.DefaultScriptSessionManager;

import com.regaltec.baf.org.user.common.valueobj.UserVO;
import com.regaltec.baf.org.user.ui.control.UserLoginBean;

public class DwrScriptSessionManagerUtil extends DefaultScriptSessionManager {

	/**
	 * 日志对象
	 */
	protected Logger logger = Logger.getLogger(getClass());
	private static final String SS_ID = "DWR_ScriptSession_Id";
	private static final String OP_ID = "userId";

	public DwrScriptSessionManagerUtil() {
		addScriptSessionListener(new ScriptSessionListener() {
			public void sessionCreated(ScriptSessionEvent ev) {
				logger.info(" script session in.....");

				HttpSession httpSession = WebContextFactory.get().getSession();
				ScriptSession scriptSession = ev.getSession();

				// 当前登录对象
				UserLoginBean loginBean = (UserLoginBean) httpSession
						.getAttribute("userLoginBean");
				UserVO userVO = null;
				String userId = null;
				if (loginBean != null) {
					userVO = loginBean.getCurrentUser();
					userId = userVO.getUserId();
				}
				// String userId = (String) httpSession.getAttribute("userId");
				if (userId == null) {
					logger.info(" script session invalidate");
					scriptSession.invalidate();
					httpSession.invalidate();
					return;
				}
				// 已经存在旧的scriptSession 注销这个旧的scriptSession
				DefaultScriptSession old = sessionMap.get(userId);
				if (old != null) {
					DwrScriptSessionManagerUtil.this.invalidate(old);
				}

				httpSession.setAttribute(SS_ID, scriptSession.getId());

				scriptSession.setAttribute(OP_ID, userId);
				scriptSession.setAttribute("SESSIONID", httpSession.getId());
				logger.info(" script session created: " + userId);
			}

			public void sessionDestroyed(ScriptSessionEvent ev) {
				ScriptSession ss = ev.getSession();
				if (ss.getAttribute(OP_ID) != null) {
					logger.info(" script session destroyed: "
							+ ss.getAttribute(OP_ID));
				}
			}
		});
	}
	// this.setScriptSessionTimeout(150000L);
}

MessagePush推送的类:

package com.ccssoft.rsas.bjflow.idcpersonentry.service;

import java.util.Collection;

import org.apache.log4j.Logger;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;

import com.ccssoft.rsas.bjflow.idcpersonentry.entity.Person;

public class MessagePush {
	public static void sendMessageAuto(String userid, String message) {
		final String userId = userid;
		final String autoMessage = message;
		final String OP_ID = "userId";
		Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
			public boolean match(ScriptSession session) {
				if (session.getAttribute(OP_ID) == null)
					return false;
				else {
					boolean f = session.getAttribute(OP_ID).equals(userId);
					return f;
				}
			}
 
		}, 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);
				}
			}
 
		});
	}
	
	
	
	/**
	 * 入室
	 * @param userid 用户id
	 * @param person 入室人员,如果为null表示不可入室
	 * @param message 后台匹配处理返回的消息
	 */
	public static void sendPersonAuto(String userid, final Person person, String message) {
		final String userId = userid;
		final String autoMessage = message;
		final String OP_ID = "userId";
		 long currentTimeMillis = System.currentTimeMillis();
	        System.out.println("开始1:"+currentTimeMillis);
	        
	        
	        
		Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
			public boolean match(ScriptSession session) {
				if (session.getAttribute(OP_ID) == null)
					return false;
				else {
					boolean f = session.getAttribute(OP_ID).equals(userId);
					return f;
				}
			}
 
		}, new Runnable() {
			private ScriptBuffer script = new ScriptBuffer();
			public void run() {
//				script.appendCall("showMessage", autoMessage);
				String info = null;
				if(person != null) {
					info = person.getId()+","+person.getPerstatus()+","+person.getAreaname();
				}
				script.appendCall("showMessage", info, autoMessage);
				Collection<ScriptSession> sessions = Browser.getTargetSessions();
				for (ScriptSession scriptSession : sessions) {
					scriptSession.addScript(script);
				}
			}
 
		});
		
		System.out.println("结束1:"+System.currentTimeMillis());
		System.out.println("耗时1: "+(System.currentTimeMillis() -currentTimeMillis ));
	}
}

前端部分:

<script type="text/javascript" src="${pageContext.request.contextPath }/dwr/engine.js"></script>   
<script type="text/javascript" src="${pageContext.request.contextPath }/dwr/util.js"></script>
function showMessage(info, autoMessage){
	//alert(person+"==="+dwr.util.toDescriptiveString(autoMessage));
	if(info == null){
		tip(autoMessage);// 提示内容
		return;
	}
	//alert(info);
	enter(info);// 自动打开窗口操作    
} 

function enter(info) {
	var infos = info.split(',');
	var queryParams = {
			'pid' : infos[0],
			'perstatus':infos[1],
			'areaname':infos[2]
		};
	personEnterroomDialog = add(datagrid, '详情信息', toShowEnterroomUrl, queryParams);
}

调用过程

// 推送
Person person = new Person();
// 身份证
person.setCertname("1");
// 身份证号
// 测试推送
idNum = "110107198904051516";
person.setCertnumber(idNum);
// IDC中心
person.setIdcs(idcs);

Page<Person> page = new Page<Person>();
page = idcEntryService.findPersonInfo(new Page<Person>(new DataGrid()), person, null, preCurrentUser);
String message = "该人员不可入室";
if(page.getCount() > 0) {
    person = page.getList().get(0);
    String id = person.getId();
    String perstatus = person.getPerstatus();
    String areaname = person.getAreaname();
    logger.info("开始进入入室页面:"+ id+", "+perstatus+", "+areaname);
    message = "入室操作";

}
else {
    person = null;
}
MessagePush.sendPersonAuto(userId, person, message);

猜你喜欢

转载自blog.csdn.net/u013474568/article/details/85089804