spring对websocket的集成和使用
WebSocket是HTML5提出的一个用于通信的协议规范,该协议通过一个握手机制,在客户端和服务端之间建立一个类似于TCP的连接,从而方便客户端和服务端之间的通信。
WebSocket协议本质上是一个基于TCP的协议,是先通过HTTP/HTTPS协议发起一条特殊的HTTP请求进行握手后创建一个用于交换数据的TCP连接,此后服务端与客户端通过此TCP连接进行实时通信。客户端和服务端只需要要做一个握手的动作,在建立连接之后,服务端和客户端之间就可以通过此TCP连接进行实时通信。
websocket是建立在物理层上的连接,相比于基于网络层的长连接可以节约资源,相比于AJAX轮训可以降低服务器压力。
spring在4.0后将websocket集成进去,要使用spring的websocket的话,spring的版本要在4.0及以上。
spring使用websocket需要的jar(pom.xml)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
web.xml中对websocket的配置
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/springMVC/spring-webSocket.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
springMVC中对websocket的xml配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> <!-- websocket处理类 -->
<bean id="msgHandler" class="com.test.websocket.MyWebSocketHandler" />
<!-- 握手接口/拦截器 ,看项目需求是否需要-->
<bean id="handshakeInterceptor" class="com.test.websocket.MyHandshakeInterceptor" />
<websocket:handlers>
<websocket:mapping path="/websocket" handler="msgHandler" />
<websocket:handshake-interceptors>
<ref bean="handshakeInterceptor" />
</websocket:handshake-interceptors>
</websocket:handlers>
<!-- 注册 sockJS,sockJs是spring对不能使用websocket协议的客户端提供一种模拟 -->
<websocket:handlers>
<websocket:mapping path="/sockjs/websocket" handler="msgHandler" />
<websocket:handshake-interceptors>
<ref bean="handshakeInterceptor" />
</websocket:handshake-interceptors>
<websocket:sockjs />
</websocket:handlers>
</beans>
springMVC中对websocket的注解配置
@Configuration
@EnableWebSocket
public class WebSocketServerConfig implements WebSocketConfigurer { @Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 添加拦截地址以及相应的websocket消息处理器
WebSocketHandlerRegistration registration = registry.addHandler(new MyWebSocketHandler(), "/websocket","sockjs/websocket");
SockJsServiceRegistration sockJS = registration.withSockJS();
// 添加拦截器
registration.addInterceptors(new MyHandshakeInterceptor());
} }
握手拦截器,继承HttpSessionHandshakeInterceptor类,做一些连接握手或者握手后的一些处理
public class MyHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
// 握手前
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
System.out
.println("++++++++++++++++ HandshakeInterceptor: beforeHandshake ++++++++++++++"
+ attributes);
return super.beforeHandshake(request, response, wsHandler, attributes);
}
// 握手后
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
System.out
.println("++++++++++++++++ HandshakeInterceptor: afterHandshake ++++++++++++++");
super.afterHandshake(request, response, wsHandler, ex);
}
}
创建MyWebSocketHandler类继承WebSocketHandler类(Spring提供的有AbstractWebSocketHandler类、TextWebSocketHandler类、BinaryWebSocketHandler类,看自己需要进行继承),该类主要是用来处理消息的接收和发送
public class MyWebSocketHandler implements WebSocketHandler {
private Logger logger = LoggerFactory.getLogger(MsgWebSocketHandler.class);
//保存用户链接
private static ConcurrentHashMap<String, WebSocketSession> users = new ConcurrentHashMap<String, WebSocketSession>();
// 连接 就绪时
@Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
users.put(session.getId(), session);
}
// 处理信息
@Override
public void handleMessage(WebSocketSession session,
WebSocketMessage<?> message) throws Exception {
System.err.println(session + "---->" + message + ":"+ message.getPayload().toString());
}
// 处理传输时异常
@Override
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
}
// 关闭 连接时
@Override
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) {
logger.debug("用户: " + session.getRemoteAddress() + " is leaving, because:" + closeStatus);
}
//是否支持分包
@Override
public boolean supportsPartialMessages() {
return false;
}
}
要进行发送消息的操作,自己可以写方法,利用保存的已经完成连接的WebSocketSession,通过调用sendMessage(WebScoketMessage<?> message)方法进行消息的发送,参数message是发送的消息内容,Spring提供的类型有TextMessage、BinaryMessage、PingMessage、PongMessage。
前端客户端JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>websocket</title>
</head>
<style type="text/css">
#div {
color: red;
}
</style>
<body>
<h1>WEBSOCKET----TEST</h1>
<div id="div"> </div>
</script>
<script type="text/javascript">
var div = document.getElementById('div');
var socket = new WebSocket('ws://127.0.0.1:8088/websocket'); socket.onopen = function(event){
console.log(event);
socket.send('websocket client connect test');
} socket.onclose = function(event){
console.log(event);
} socket.onerror = function(event){
console.log(event);
} socket.onmessage = function(event){
console.log(event)
div.innerHTML += (' @_@ ' + event.data + ' ~_~ ');
}
</script>
</body>
</html>
其实在后台也可以进行websocket客户端的创建
@Test
public void connectTest(){
WsWebSocketContainer wsWebSocketContainer = new WsWebSocketContainer();
wsWebSocketContainer.setDefaultMaxSessionIdleTimeout(300);
StandardWebSocketClient client = new StandardWebSocketClient(wsWebSocketContainer);
WebSocketHandler webSocketHandler = new MyWebSocketHandler();
String uriTemplate = "ws://127.0.0.1:8088/websocket?account=11111";
Object uriVars = null;
ListenableFuture<WebSocketSession> future = client.doHandshake(webSocketHandler, uriTemplate, uriVars);
try {
WebSocketSession session = future.get();
session.sendMessage(new TextMessage("hello world"));
} catch (InterruptedException | ExecutionException | IOException e) {
e.printStackTrace();
} } @Test
public void connectTest2(){
StandardWebSocketClient client = new StandardWebSocketClient();
WebSocketHandler webSocketHandler = new MyWebSocketHandler();
String uriTemplate = "ws://127.0.0.1:8088/websocket";
UriComponentsBuilder fromUriString = UriComponentsBuilder.fromUriString(uriTemplate);
fromUriString.queryParam("account","111111");
/*
* 作用同上,都是将请求参数填入到URI中
* MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
* params.add("account","111111");
* fromUriString.queryParams(params);
* */
URI uri = fromUriString.buildAndExpand().encode().toUri();
WebSocketHttpHeaders headers = null;
ListenableFuture<WebSocketSession> doHandshake = client.doHandshake(webSocketHandler, headers , uri);
try {
WebSocketSession session = doHandshake.get();
session.sendMessage(new TextMessage("hello world"));
} catch (InterruptedException | ExecutionException | IOException e) {
e.printStackTrace();
} }
这是我利用Junit进行的测试,实验证明是可以完成websocket的连接。
注意:websocket在进行连接的时候是可以类似get请求一样,将参数拼接到url中。还可以自己将参数封装进URI中,利用另一个方法进行连接的握手操作。
spring对websocket的集成和使用的更多相关文章
- tomcat 7下spring 4.x mvc集成websocket以及sockjs完全参考指南
之所以sockjs会存在,说得不好听点,就是因为微软是个流氓,现在使用windows 7的系统仍然有近半,而windows 7默认自带的是ie 8,有些会自动更新到ie 9,但是大部分非IT用户其实都 ...
- tomcat 7下spring 4.x mvc集成websocket以及sockjs完全参考指南(含nginx/https支持)
之所以sockjs会存在,说得不好听点,就是因为微软是个流氓,现在使用windows 7的系统仍然有近半,而windows 7默认自带的是ie 8,有些会自动更新到ie 9,但是大部分非IT用户其实都 ...
- Spring Chapter4 WebSocket 胡乱翻译 (二)
书接上文,Spring Chapter4 WebSocket 胡乱翻译 (一) 4.4.4. 消息流 一旦暴露了STOMP端点,Spring应用程序就成为连接客户端的STOMP代理. 本节介绍服务器端 ...
- Spring Chapter4 WebSocket 胡乱翻译 (一)
4. WebSocket 包含了Servlet stack,原生WebSocket交互,通过SockJS模拟,并且通过STOMP在WebSocket之上订阅.发布消息. 4.1 简介 不扯了,看到这个 ...
- Spring+SpringMvc+Mybatis框架集成搭建教程
一.背景 最近有很多同学由于没有过SSM(Spring+SpringMvc+Mybatis , 以下简称SSM)框架的搭建的经历,所以在自己搭建SSM框架集成的时候,出现了这样或者那样的问题,很是苦恼 ...
- NoSql存储日志数据之Spring+Logback+Hbase深度集成
NoSql存储日志数据之Spring+Logback+Hbase深度集成 关键词:nosql, spring logback, logback hbase appender 技术框架:spring-d ...
- 菜鸟学习Spring——60s学会Spring与Hibernate的集成
一.概述. Spring与Hibernate的集成在企业应用中是很常用的做法通过Spring和Hibernate的结合能提高我们代码的灵活性和开发效率,下面我就一步一步的给大家讲述Spring如何和H ...
- 玩转spring boot——websocket
前言 QQ这类即时通讯工具多数是以桌面应用的方式存在.在没有websocket出现之前,如果开发一个网页版的即时通讯应用,则需要定时刷新页面或定时调用ajax请求,这无疑会加大服务器的负载和增加了客户 ...
- spring boot / cloud (三) 集成springfox-swagger2构建在线API文档
spring boot / cloud (三) 集成springfox-swagger2构建在线API文档 前言 不能同步更新API文档会有什么问题? 理想情况下,为所开发的服务编写接口文档,能提高与 ...
随机推荐
- [译]HAL-超文本应用语言
[译]HAL-超文本应用语言 精益超媒体类型 总结 HAL 是一种简单的格式,它提供了一种一致且简便的方法在 API 的资源之间进行超链接. 采用 HAL 将使您的 API 易于探索,并且其文档很容易 ...
- Vmware Centos 与 windows 创建共享目录
一路路都是坑~~ 只为了安装orcle的jdk~~,然而Orcle下载jdk是需要登录才能下载的,所以我在Centos7下使用 wget / curl 都下载不了哦~jdk7 第一步:Vmvare ...
- Hadoop权威指南(中文版-带目录索引)pdf电子书
Hadoop权威指南(中文版-带目录索引)pdf电子书下载地址:百度网盘点击下载:链接:https://pan.baidu.com/s/1E-8eLaaqTCkKESNPDqq0jw 提取码:g6 ...
- JavaScript基础1228JavaScript:void(0)开始----
JavaScript:void(0)含义 JavaScript:void(0)含义 我们经常会使用到JavaScript:void(0)这样的代码,那么在JavaScript中JavaScript:v ...
- python信息收集(二)
在第二层主机发现中,除了使用arping命令外,还可以使用Kali下自带的一个工具----netdiscover. netdiscover是一个专门用于二层主机发现的工具,它有两种扫 ...
- gojs去水印
重点在go.js文件中将这个方法中的代码注释掉即可 搜索关键字 7ca11abfd022028846 然后注释下列代码,注释前先整理JS格式 function ni() { if(th) { var ...
- PG TO Oracle 增量同步-外部表
背景 最近在负责公司数据Oracle转PG:老平台数据库:Oracle11g:新平台数据库:PostgreSQL12.由于平台统计规则有变动:所以正在推广的游戏数据无法全部迁移过来:只能在老平台上运行 ...
- NGINX反向代理,后端服务器获取真实IP
一般使用中间件做一个反向代理后,后端的web服务器是无法获取到真实的IP地址. 但是生产上,这又是不允许的,那么怎么解决? 1.在NGINX反向代理服务器上进行修改 2.修改后端web服务器配置文件 ...
- Ubuntu 安装 Qt, 安装辅助软件
sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev sudo apt-get install gcc g++ sudo apt-get inst ...
- 新版gitbook导出pdf
文章目录 gitbook自带的npm模块gitbook 使用vscode的插件Markdown PDF 使用CommandBox GitBook Exporter 最近想把自己写的一个gitbook转 ...