Springmvc+WebSocket整合
WebSocket是为解决客户端与服务端实时通信而产生的技术。其本质是先通过HTTP/HTTPS协议进行握手后创建一个用于交换数据的TCP连接,此后服务端与客户端通过此TCP连接进行实时通信。
以前我们实现推送技术,用的都是轮询,在特点的时间间隔有浏览器自动发出请求,将服务器的消息主动的拉回来,在这种情况下,我们需要不断的向服务器 发送请求,然而HTTP request 的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽和服务器资源。会占用大量的带宽和服务器资源。
WebSocket 最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。在建立连接之后,服务器可以主动传送数据给客户端。此外,服务器与客户端之间交换的标头信息很小。
WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息。
如何使用?
注意:spring4.0以后加入了对websocket技术的支持,base项目的spring版本为3.1.4,升到4.0.2后加入spring自带的websocket包。
1、maven pom.xml加入websocket所依赖的jar包
<!-- websocket -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.0.1.RELEASE</version>
</dependency>
2、在servlet-context中添加
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd
3、创建websocket的处理类
handleTextMessage
消息处理方法,接收会话中前端发送给后台的message,再通过sendMessage发送到前端
afterConnectionEstablished 连接建立后处理方法
afterConnectionClosed 连接关闭后处理方法
package cn.com.bmsoft.base.websocket;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import cn.com.bmsoft.base.service.face.management.IGasService;
import cn.com.bmsoft.base.service.face.management.IHomeMonitorService;
import cn.com.bmsoft.base.service.face.management.IInfraredService;
@RequestMapping("websocket")
public class WebsocketEndPoint extends TextWebSocketHandler {
@Autowired
IHomeMonitorService homeMonitorService;
@Autowired
IGasService gasService;
@Autowired
IInfraredService infraredService;
@Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
super.handleTextMessage(session, message);
String phonemessage = message.getPayload();
session.sendMessage(message);
}
@Override
public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(1);
System.out.println("Connection Establied!");
newScheduledThreadPool.scheduleWithFixedDelay(new TimerTask() {
public void run() {
try {
Map<String, Object> queryParams = new HashMap<String, Object>();
queryParams.put("gStatus","1");
queryParams.put("iStatus","1");
//查询未通知异常条数
int gwarns = gasService.count(queryParams);
int iwarns = infraredService.count(queryParams);
if((gwarns+iwarns)!=0){
session.sendMessage(new TextMessage((gwarns+iwarns)+""));
}else{
session.sendMessage(new TextMessage(0+""));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 0, 5000, TimeUnit.MILLISECONDS);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("Connection Closed!");
}
}
4、创建握手协议
package cn.com.bmsoft.base.websocket;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import java.util.Map;
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
}
5、servletcontext配置处理类和握手协议
<!-- spring-websocket配置start-->
<bean id="websocket" class="cn.com.bmsoft.base.websocket.WebsocketEndPoint" />
<websocket:handlers>
<websocket:mapping path="/websocket" handler="websocket" />
<websocket:handshake-interceptors>
<bean class="cn.com.bmsoft.base.websocket.HandshakeInterceptor" />
</websocket:handshake-interceptors>
</websocket:handlers>
<!-- spring-websocket配置end-->
6、客户端页面
<!DOCTYPE html>
<html>
<head>
<title>websocket example</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=8,9,10" />
<style type="text/css">
#connect-container {
float: left;
width: 400px
}
#connect-container div {
padding: 5px;
}
#console-container {
float: left;
margin-left: 15px;
width: 400px;
}
#console {
border: 1px solid #CCCCCC;
border-right-color: #999999;
border-bottom-color: #999999;
height: 170px;
overflow-y: scroll;
padding: 5px;
width: 100%;
}
#console p {
padding: 0;
margin: 0;
}
</style>
<!-- <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script> -->
<script type="text/javascript" src="${requestContext.contextPath}/resources/scripts/sockjs-0.3.min.js"></script>
<script type="text/javascript">
var ws = null;
var url = null;
var transports = [];
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('echo').disabled = !connected;
}
function connect() {
alert("url:"+url);
if (!url) {
alert('Select whether to use W3C WebSocket or SockJS');
return;
}
ws = new WebSocket(url); //申请一个WebSocket对象
ws.onopen = function () {
setConnected(true);
log('Info: connection opened.');
};
ws.onmessage = function (event) {
//var msgJson=eval("("+event.data+")");
log('Received: ' +event.data);
};
ws.onclose = function (event) {
setConnected(false);
log('Info: connection closed.');
log(event);
};
}
function disconnect() {
if (ws != null) {
ws.close();
ws = null;
}
setConnected(false);
}
function echo() {
if (ws != null) {
var message = document.getElementById('message').value;
log('Sent: ' + message);
var msg = '"frdId":"'+28+'",'
+ '"content":"'
+ message + '"';
ws.send(msg);
// ws.send(message);
} else {
alert('connection not established, please connect.');
}
}
function updateUrl(urlPath) {
if (window.location.protocol == 'http:') {
url = 'ws://' + window.location.host + urlPath;
} else {
url = 'wss://' + window.location.host + urlPath;
}
}
function log(message) {
var console = document.getElementById('console');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(message));
console.appendChild(p);
while (console.childNodes.length > 25) {
console.removeChild(console.firstChild);
}
console.scrollTop = console.scrollHeight;
}
</script>
</head>
<script type="text/javascript" src="${requestContext.contextPath}/resources/scripts/jquery-${jqueryVersion}.min.js"></script>
<script type="text/javascript">
$(function(){
//移除顶端遮罩
if (top.hideMask) top.hideMask();
});
</script>
<body>
<div>
<div id="connect-container">
<input id="radio1" type="radio" name="group1" onclick="updateUrl('/base/websocket');">
<label for="radio1">W3C WebSocket</label>
<div>
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
</div>
<div>
<textarea id="message" style="width: 350px">Here is a message!</textarea>
</div>
<div>
<button id="echo" onclick="echo();" disabled="disabled">Echo message</button>
</div>
</div>
<div id="console-container">
<div id="console"></div>
</div>
</div>
</body>
</html>
sockjs-0.3.min.js
链接:http://pan.baidu.com/s/1c2uLpDY 密码:5zxh
Springmvc+WebSocket整合的更多相关文章
- spring+websocket整合
java-websocket的搭建非常之容易,没用框架的童鞋可以在这里下载撸主亲自调教好的java-websocket程序: Apach Tomcat 8.0.3+MyEclipse+maven+JD ...
- Spring+springmvc+Mybatis整合案例 annotation版(myeclipse)详细版
Spring+springmvc+Mybatis整合案例 Version:annotation版 文档结构图: 从底层开始做起: 01.配置web.xml文件 <?xml version=&qu ...
- Spring+springmvc+Mybatis整合案例 xml配置版(myeclipse)详细版
Spring+springmvc+Mybatis整合案例 Version:xml版(myeclipse) 文档结构图: 从底层开始做起: 01.配置web.xml文件 <?xml version ...
- SpringMVC+redis整合
在网络上有一个很多人转载的springmvc+redis整合的案例,不过一直不完整,也是被各种人装来转去,现在基本将该框架搭建起来. package com.pudp.bae.base; import ...
- sonne_game网站开发03 spring-mvc+freemarker整合
今天的任务就是在spring+mybatis+springmvc的基础上,将freemarker整合进来. freemarker是什么? freemarker是一种模板引擎.它的目的是基于模板和数据, ...
- SpringMVC 中整合之JSON、XML
每次看到好的博客我就想好好的整理起来,便于后面自己复习,同时也共享给网络上的伙伴们! 博客地址: springMVC整合Jaxb2.xStream: http://www.cnblogs.com/h ...
- 框架篇:Spring+SpringMVC+hibernate整合开发
前言: 最近闲的蛋疼,搭个框架写成博客记录下来,拉通一下之前所学知识,顺带装一下逼. 话不多说,我们直接步入正题. 准备工作: 1/ IntelliJIDEA的安装配置:jdk/tomcat等..(本 ...
- IDEA下使用maven构建web项目(SpringMVC+Mybatis整合)
需求背景:由于最近总是接到一些需求,需要配合前端团队快速建设移动端UI应用或web应用及后台业务逻辑支撑的需求,若每次都复用之前复杂业务应用的项目代码,总会携带很多暂时不会用到的功能或组件,这样的初始 ...
- 框架篇:Spring+SpringMVC+Mybatis整合开发
前言: 前面我已搭建过ssh框架(http://www.cnblogs.com/xrog/p/6359706.html),然而mybatis表示不服啊. Mybatis:"我抗议!" ...
随机推荐
- leetcode-algorithms-36 Valid Sudoku
leetcode-algorithms-36 Valid Sudoku Determine if a 9x9 Sudoku board is valid. Only the filled cells ...
- Leetcode 869. 重新排序得到 2 的幂
869. 重新排序得到 2 的幂 显示英文描述 我的提交返回竞赛 用户通过次数102 用户尝试次数134 通过次数103 提交次数296 题目难度Medium 从正整数 N 开始,我们按任何顺序 ...
- python 小练习 5
Py从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992, 这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和 ...
- [洛谷 P2709] 小B的询问
P2709 小B的询问 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数 ...
- Android Studio build gradle project info 卡主不动解决方法.
项目里的: build.gradle 依赖 的gradle 版本 在每个项目里 gradle/wrapper/properties/gradle-wrapper.properties 配置文件里 用户 ...
- kdbg安装使用教程(kali)
一.背景说明 所谓调试者,主要就是下断点.观察变量,不是太复杂的事情也不用太复杂的工具. 但具体到linux平台而言,gdb本来多敲几下命令也不是不可以的事,但是一个屏幕就那么大打印出一堆东西又乱又看 ...
- snort安装使用教程(CentOS6.5)
官网:https://www.snort.org/ 官方文档:https://www.snort.org/documents 2.安装 2.1安装依赖 yum install flex bison - ...
- Linux查看某个命令属于哪个包
有时修我们需要某个命令但其没有安装,提供该命令的包名也与命令名相差很大直接查找命令名找不到包,如rexec. 此时我们就非常需要这样一个工具:可以根据最终的命令查找提供该命令的软件包. 类型 命令 说 ...
- 在springboot中验证表单信息(六)
构建工程 创建一个springboot工程,由于用到了 web .thymeleaf.validator.el,引入相应的起步依赖和依赖,代码清单如下: 1 2 3 4 5 6 7 8 9 10 11 ...
- shell脚本学习之参数传递
shell之参数传递 我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n.n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推…… 实例 以 ...