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:"我抗议!" ...
随机推荐
- ubuntu开启慢日志
ubuntu 开启mysql日志记录 1.找到mysql的配置文件sudo vim /etc/mysql/my.cnf将下面两行的#去掉#general_log_file = /var/log/mys ...
- bzoj-2038-莫队
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 15784 Solved: 7164[Sub ...
- 11204RAC-dbca建库脚本
SET VERIFY OFFconnect "SYS"/"&&sysPassword" as SYSDBAset echo onspool /u ...
- 安装docker No package docker available
安装docker 时候出现以下问题 yum -y install dockerLoaded plugins: fastestmirrorDetermining fastest mirrors * ba ...
- 【Python】Anaconda配置
Anaconda 是一个用于科学计算的Python发行版,支持 Linux.Mac.Windows 系统,提供了包管理与环境管理的功能,可以很方便地解决多版本 Python 并存.切换以及各种第三方包 ...
- E - Let's Go Rolling!
题目描述:数轴上有nn个质点,第ii个质点的坐标为xixi,花费为cici,现在要选择其中一些点固定,代价为这些点的花费,固定的点不动,不固定的点会向左移动直至遇到固定的点,代价是这两点的距离,如果左 ...
- 什么是 开发环境、测试环境、生产环境、UAT环境、仿真环境
开发环境:开发环境是程序猿们专门用于开发的服务器,配置可以比较随意, 为了开发调试方便,一般打开全部错误报告. 测试环境:一般是克隆一份生产环境的配置,一个程序在测试环境工作不正常,那么肯定不能把它发 ...
- Linux几种服务用处介绍
rexec--Remote Execute,远程命令执行,允许远程机器在本机上远程执行命令,监听端口512. nfs--Network File System,网络文件系统,用于将本机文件夹共享到别的 ...
- Vuex的深入学习
1.vuex 的dispatch和commit提交mutation的区别 (1)当你的操作行为中含有异步操作,比如向后台发送请求获取数据,就需要使用action的dispatch去完成了.其他使用co ...
- 批量生成QRcode
本想在excel批量生成GUID,并生成二维码. //Excel生成guid,uuid 格式:600d65bc-948a---fd8dfeebb1cd =LOWER(CONCATENATE(DEC2H ...