一、概述
1. 本篇文章以聊天室程序为例,介绍实现消息推送给的几种方式。
2. 基于Spring Boot,其他框架或语言也类似,项目地址:https://github.com/yeta666/chat
3. 文中只提及主要代码,详细内容看项目。
二、DWR
1. 引入依赖
<dependency>
<groupId>org.directwebremoting</groupId>
<artifactId>dwr</artifactId>
<version>3.0.2-RELEASE</version>
</dependency>
2. 创建提供服务的类
@RestController
@RemoteProxy
public class DWRController {
/**
* 根据请求参数type处理不同类型请求
* @param reqMessage
*/
@RemoteMethod
public void chat(String reqMessage) {
//请求
CommonRequest request = JSON.parseObject(reqMessage, CommonRequest.class);
Integer type = request.getType();
//返回
CommonResponse response;
//所有会话
WebContext webContext = WebContextFactory.get();
Collection<ScriptSession> sessions = webContext.getAllScriptSessions();
//构建发送所需的JS脚本
ScriptBuffer scriptBuffer = new ScriptBuffer();
if (type == 1) { //群聊消息
//调用客户端的JS脚本函数
scriptBuffer.appendScript("chat(");
//这个message可以被过滤处理一下,或者做其他的处理操作。这视需求而定。
response = new CommonResponse(1000, 1, request.getMessage());
scriptBuffer.appendData(JSON.toJSONString(response));
scriptBuffer.appendScript(")");
Util util = new Util(sessions); //sessions,群发
util.addScript(scriptBuffer);
} else if (type == 2) { //私聊消息
for (ScriptSession session : sessions) {
if (session.getId().equals(request.getTarget())) {
//调用客户端的JS脚本函数
scriptBuffer.appendScript("chat(");
//这个message可以被过滤处理一下,或者做其他的处理操作。这视需求而定。
response = new CommonResponse(1000, 2, request.getMessage());
scriptBuffer.appendData(JSON.toJSONString(response));
scriptBuffer.appendScript(")");
Util util = new Util(session); //session,单独发
util.addScript(scriptBuffer);
}
}
} else if (type == 3) { //返回所有会话id,用于私聊
List<String> ids = new ArrayList<String>();
for (ScriptSession session : sessions) {
ids.add(session.getId());
}
//调用客户端的JS脚本函数
scriptBuffer.appendScript("addTarget(");
//这个message可以被过滤处理一下,或者做其他的处理操作。这视需求而定。
response = new CommonResponse(1000, 4, ids);
scriptBuffer.appendData(JSON.toJSONString(response));
scriptBuffer.appendScript(")");
Util util = new Util(sessions); //sessions,群发
util.addScript(scriptBuffer);
}
}
}
3. 创建dwr配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd">
<dwr:annotation-config/>
<dwr:annotation-scan scanRemoteProxy="false" base-package="com.yeta.chat.dwr.DWRController"/>
<dwr:configuration/>
</beans>
4. 配置dwrServlet
/**
* 配置dwr Servlet
* 重点注意取名
* @return
*/
@Bean
public ServletRegistrationBean dwrServlet() {
DwrSpringServlet servlet = new DwrSpringServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(servlet, "/dwr/*");
registrationBean.addInitParameter("debug", "true");
//使用服务器反转Ajax
registrationBean.addInitParameter("activeReverseAjaxEnabled", "true");
//能够从其他域请求true:开启; false:关闭
registrationBean.addInitParameter("crossDomainSessionSecurity", "false");
//允许远程调用JS
registrationBean.addInitParameter("allowScriptTagRemoting", "true");
return registrationBean;
}
5. 导入dwr的配置文件
@ImportResource(locations = "classpath:config/dwrConfig.xml")
6. 引入dwr相关js,注意路径,文件由dwr自动生成,不会在项目中出现
<script type='text/javascript' src='/chat/dwr/util.js'></script>
<script type='text/javascript' src='/chat/dwr/engine.js'></script>
<script type='text/javascript' src='/chat/dwr/interface/DWRController.js'></script>
7. 主要js代码
$(function() {
//页面加载时进行反转的激活
dwr.engine.setActiveReverseAjax(tru