前言
在web开发时,有时我们需要一些实时性比较高的数据反馈,如设备监测、系统监测、聊天等,这时使用http显然是不适合的,这时就需要用到websocket通过单次连接来获取长时间的数据获取。
什么是websocket?
websocket 是一种在单个 tcp 连接上实现全双工(双向)通信的网络协议,由 html5 规范定义,旨在它允许客户端(如浏览器)和服务器之间建立持久连接,双方可以随时向对方发送数据,而无需像 http 那样每次通信都重新建立连接。
本篇文章就是记录springboot如何集成websocket功能,废话不多说,让我们开始吧~
环境准备
因为要使用websocket,所以在除了集成基础的spring-boot-starter-web 依赖以外,还要集成
spring-boot-starter-websocket 以获得websocket支持。
pom.xml
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceencoding>utf-8</project.build.sourceencoding>
</properties>
<dependencies>
<!--web依赖-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<!--websocket依赖-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-websocket</artifactid>
<version>2.3.12.release</version>
</dependency>
</dependencies>代码步骤
配置websocket节点
在配置类里,我们需要新建一个serverendpointexporter 并交给springboot管理,即可开启websocket节点功能,内容如下:
@configuration
public class websocketconfig {
/**
* 注入serverendpointexporter,
* 这个bean会自动注册使用了@serverendpoint注解声明的websocket endpoint
*/
@bean
public serverendpointexporter serverendpointexporter() {
return new serverendpointexporter();
}
}创建websocket节点
首先需要在需使用到的websocket类上添加@serverendpoint(path,config) 以标记该类会作为一个websokcet的节点类,其中
- path:该节点的访问路径
- config: 可以做一些额外配置,如该节点的访问权限校验。
如下:
@component
@slf4j
@serverendpoint(value = "/detail", configurator = websocketauthconfig.class)
public class detailserver {}下面就可以在该类中以事件标注的方式定义我们的方法,可以使用以下注解:
- @onopen :在有新的连接接入时,触发方法。
- @onmessage: 当有新的消息时,触发方法。
- @onerror:当发生错误时,触发方法。
- @onclose:当连接断开时,触发方法。
例如下面的方法定义:
@onopen
public void onopen(session session) {
//这里一般会存储会话。
log.info("【websocket消息】有新的连接");
}
/**
* 链接关闭调用的方法
*/
@onclose
public void onclose() {
//这里会移除会话。
log.info("【websocket消息】连接断开");
}
@onmessage
public void onmessage(string message) {
log.info("【websocket消息】收到客户端消息:" + message);
}
@onerror
public void onerror(session session, throwable error) {
log.error("用户错误,原因:" + error.getmessage());
}一般会创建一个用于存储当前当前session的map,用于会话的管理,并可以通过
session.getasyncremote().sendtext(message);
将message数据发送到已连接的前端页面。
授权验证
当然不能允许所有人连接我们定义的websokcet节点,我们可以通过继承serverendpointconfig.configurator 来对节点进行配置,一般可以用于添加请求配置或进行授权认证,如下实现了一个jwt的token验证:
@slf4j
public class websocketauthconfig extends serverendpointconfig.configurator {
/**
* des:[拦截websocket的请求头,并验证]
*
* @param originheadervalue 请求头
* @return boolean
* @link [java.lang.string]
*/
@override
public boolean checkorigin(final string originheadervalue) {
final servletrequestattributes servletrequestattributes = (servletrequestattributes) requestcontextholder.getrequestattributes();
try {
assert servletrequestattributes != null;
/*
此处使用反射的方式获取对象,无法@autowiredw自动注入
*/
final jwtutil jwtutil = springutil.getbean(jwtutil.class);
httpservletresponse response = servletrequestattributes.getresponse();
httpservletrequest request = servletrequestattributes.getrequest();
//获取并验证请求参数中的token参数
final string token = servletrequestattributes.getrequest().getparameter("token");
final claims claims = jwtutil.getclaimsbytoken(token);
if (objectutil.isnull(claims)) {
/*
token验证失败,拒绝链接
*/
log.info("token错误,拒绝连接......");
request.getsession().setattribute("loginfill",true);
return false;
}else {
request.getsession().setattribute("loginfill",false);
}
} catch (final exception e) {
log.error("websocket-auth-error", e);
}
return true;
}
}当然这里也可以通过shiro的根据路径配置拦截请求,这里也是支持的,这样serverendpointconfig.configurator就可以不用单独配置。
总结
通过上述方式,就可以建立一个比较完善的websocket节点,在实际开发过程中可以解决一些实时性要求较高的数据传输。当然,实现websocket并不只是有这一种方式,也可以通过netty框架去自己实现,这样在高并发系统下的效率会更高。
到此这篇关于springboot集成websokcet的文章就介绍到这了,更多相关springboot集成websokcet内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论