[超详细]SpringBoot整合WebSocket
1. 什么是WebSocket?
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它允许在浏览器和服务器之间进行实时的、双向的通信。相对于传统的基于请求和响应的 HTTP 协议,WebSocket 提供了一种更有效、更实时的通信方式,适用于需要实时更新、实时通知和实时交互的应用。
WebSocket 的一些关键特点包括:
- 全双工通信: WebSocket 允许服务器和客户端在同一连接上同时进行双向通信。这意味着服务器可以随时向客户端推送数据,而不必等待客户端发送请求。
- 持久连接: WebSocket 连接一旦建立,会一直保持打开状态,不会像传统的 HTTP 连接那样在每次请求和响应之后关闭。这减少了每次连接建立和关闭的开销,使通信更加高效。
- 低延迟: 由于连接保持打开状态,WebSocket 通信具有较低的延迟,适用于实时性要求较高的应用,如实时聊天、实时数据更新等。
- 少量的数据交换: 与 HTTP 请求和响应相比,WebSocket 数据交换的开销较小。WebSocket 的帧头相对较小,因此有效载荷的比例更高。
- 兼容性: 现代浏览器和大多数服务器支持 WebSocket。此外,WebSocket 协议还定义了一个子协议 STOMP(Streaming Text Oriented Messaging Protocol),用于更高级的消息传递和订阅功能。
- 安全性: 与其他网络通信协议一样,WebSocket 通信也需要一些安全性的考虑。可以使用加密协议(如 TLS)来保护数据在网络传输中的安全性。
2. 代码实战
2.1 SpringBoot导入依赖
在pom.xml中导入以下依赖,版本由SpringBoot管理
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.2 创建配置类
创建WebSocketConfig配置类,并将其注入到Bean容器中
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2.3 创建WebSocketServer类
创建WebSocketServer类,并将其注入到Bean容器中
注意:@ServerEndpoint("/WebSocket"),该注解用于配置建立WebSocket连接的路径,可以按需修改。
该类一般拥有以下功能:
- WebSocket 端点注册: WebSocket 服务器需要注册一个或多个 WebSocket 端点(Endpoints)。每个端点对应一种处理逻辑,可以处理客户端发送过来的消息,以及向客户端发送消息。这些端点通过注解或配置来定义。
- 建立和维护连接: WebSocket 服务器负责监听客户端的连接请求,一旦有客户端连接,服务器会创建一个 WebSocket 会话(Session)来管理这个连接。服务器需要能够维护这些连接,包括打开、关闭、保持心跳等操作。
- 消息处理: 一旦客户端连接成功,WebSocket 服务器需要处理客户端发送过来的消息。这可以在 WebSocket 端点中的方法上定义处理逻辑。服务器可以根据不同的业务需求处理不同类型的消息。
- 处理异常: 与任何网络通信一样,WebSocket 连接可能会面临各种异常情况,如断开连接、网络问题等。WebSocket 服务器需要能够处理这些异常情况,进行适当的清理和处理。
可以将该类理解为WebSocket生命周期中会调用的方法。
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
@Slf4j
@Component
@ServerEndpoint("/WebSocket")
public class WebSocketServer {
private Session session;
@OnOpen
public void onOpen(Session session) {
this.session = session;
WebSocketManager.sentToUser(session, "WebSocket is connected!");
WebSocketManager.addWebSocketServer(this);
log.info("与SessionId:{}建立连接", session.getId());
}
@OnClose
public void onClose() {
WebSocketManager.removeWebSocketServer(this);
log.info("WebSocket连接关闭");
}
@OnMessage
public void onMessage(String message, Session session) {
log.info("来自SessionId:{}的消息:{}", session.getId(), message);
}
@OnError
public void onError(Session session, Throwable error) {
log.error("Session:{}的WebSocket发生错误", session.getId(), error);
}
public Session getSession() {
return session;
}
public String getSessionId() {
return session.getId();
}
}
2.4 创建WebSocketServer管理类
该类用于管理WebSocketServer(其实主要是管理Session),如果不需要发送消息给特定用户,那么无需创建该类,在WebSocketServer类中维护一个类变量即可。
import lombok.extern.slf4j.Slf4j;
import javax.websocket.Session;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@Slf4j
public class WebSocketManager {
private final static CopyOnWriteArraySet<WebSocketServer> webSocketServerSet = new CopyOnWriteArraySet<>();
private final static ConcurrentHashMap<String, WebSocketServer> webSocketServerMap = new ConcurrentHashMap<>();
public static void addWebSocketServer(WebSocketServer webSocketServer){
if (webSocketServer != null){
webSocketServerSet.add(webSocketServer);
webSocketServerMap.put(webSocketServer.getSessionId(), webSocketServer);
}
}
public static void removeWebSocketServer(WebSocketServer webSocketServer){
webSocketServerSet.remove(webSocketServer);
webSocketServerMap.remove(webSocketServer.getSessionId());
}
/**
* 通过SessionId发送消息给特定用户
* @param
* @param msg
*/
public static void sentToUser(String sessionId, String msg){
Session session = webSocketServerMap.get(sessionId).getSession();
sentToUser(session, msg);
}
/**
* 通过Session发送消息给特定用户
* @param session
* @param msg
*/
public static void sentToUser(Session session, String msg){
if (session == null){
log.error("不存在该Session,无法发送消息");
return;
}
session.getAsyncRemote().sendText(msg);
}
/**
* 发送消息给所有用户
* @param msg
*/
public static void sentToAllUser(String msg){
for (WebSocketServer webSocketServer : webSocketServerSet) {
sentToUser(webSocketServer.getSession(), msg);
}
log.info("向所有用户发送WebSocket消息完毕,消息:{}", msg);
}
}
3. 测试
使用Postman等工具进行WebSocket连接,连接路径为WebSocket(与前文的@ServerEndpoint内容一致)。建立连接后会收到"WebSocket is connected!"
4. 后续完善
如果你的项目中有登录功能,那么应该在你的登录时将用户的Session记录下来。你可以将Session记录在本地缓存、Redis和Grava缓存等能够建立关联关系的地方。
[超详细]SpringBoot整合WebSocket的更多相关文章
- Springboot整合Websocket遇到的坑
Springboot整合Websocket遇到的坑 一.使用Springboot内嵌的tomcat启动websocket 1.添加ServerEndpointExporter配置bean @Confi ...
- SpringBoot 整合 WebSocket
SpringBoot 整合 WebSocket(topic广播) 1.什么是WebSocket WebSocket为游览器和服务器提供了双工异步通信的功能,即游览器可以向服务器发送消息,服务器也可以向 ...
- springboot整合websocket原生版
目录 HTTP缺点 HTTP websocket区别 websocket原理 使用场景 springboot整合websocket 环境准备 客户端连接 加入战队 微信公众号 主题 HTTP请求用于我 ...
- SpringBoot整合websocket简单示例
依赖 <!-- springboot整合websocket --> <dependency> <groupId>org.springframework.boot&l ...
- springboot整合websocket高级版
目录 sockjs介绍 产生的原因 环境搭建 springboot整合sockjs 使用场景 聊天室开发 点对点通信 群聊 效果 总结 加入战队 微信公众号 上一章节我们说了websocket的优缺点 ...
- WebSocket的简单认识&SpringBoot整合websocket
1. 什么是WebSocket?菜鸟对websocket的解释如下 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务 ...
- springboot整合websocket实现客户端与服务端通信
定义 WebSocket是通过单个TCP连接提供全双工(双向通信)通信信道的计算机通信协议.此WebSocket API可在用户的浏览器和服务器之间进行双向通信.用户可以向服务器发送消息并接收事件驱 ...
- 【Java分享客栈】SpringBoot整合WebSocket+Stomp搭建群聊项目
前言 前两周经常有大学生小伙伴私信给我,问我可否有偿提供毕设帮助,我说暂时没有这个打算,因为工作实在太忙,现阶段无法投入到这样的领域内,其中有两个小伙伴又问到我websocket该怎么使用,想给自己的 ...
- Springboot整合WebSocket实现网页版聊天,快来围观!
- springboot整合websocket后运行测试类报错:javax.websocket.server.ServerContainer not available
springboot项目添加websocket依赖后运行测试类报如下错误: org.springframework.beans.factory.BeanCreationException: Error ...
随机推荐
- es 笔记二之基础查询
本文首发于公众号:Hunter后端 原文链接:es笔记二之基础查询 这一篇笔记介绍 es 的基础查询. 基础查询包括很多,比如排序,类似数据库 limit 的操作,like 操作,与或非等,对于这些操 ...
- 深度学习基础入门篇[8]::计算机视觉与卷积神经网络、卷积模型CNN综述、池化讲解、CNN参数计算
深度学习基础入门篇[8]::计算机视觉与卷积神经网络.卷积模型CNN综述.池化讲解.CNN参数计算 1.计算机视觉与卷积神经网络 1.1计算机视觉综述 计算机视觉作为一门让机器学会如何去"看 ...
- Java的标识符、关键字、 常量、变量、数据类型、 数据类型转换、字符ASCII码表(基础语法的学习)
一.Java的关键字和标识符 关键字 1.定义: 在Java程序中,已经定义好的被预先使用的一些特殊的单词称为关键字,一共有50个关键字(48+2个保留字),关键字都是小写的英文单词 2.关键字的分类 ...
- 2023-06-02:给定一个二进制数组 nums 和一个整数 k, k位翻转 就是从 nums 中选择一个长度为 k 的 子数组, 同时把子数组中的每一个 0 都改成 1 ,把子数组中的每一个 1
2023-06-02:给定一个二进制数组 nums 和一个整数 k, k位翻转 就是从 nums 中选择一个长度为 k 的 子数组, 同时把子数组中的每一个 0 都改成 1 ,把子数组中的每一个 1 ...
- SQL Server 日志传输还原作业执行缓慢
目录 情景 故障定位 VLF 对 Restore 的影响 问题 解决方案 方案1 方案 2 参考资料 情景 IP 角色 192.168.1.61 Primary 192.168.1.59 Second ...
- ASP.NET Core 6框架揭秘实例演示[37]:重定向的N种实现方式
在HTTP的语义中,重定向一般指的是服务端通过返回一个状态码为3XX的响应促使客户端像另一个地址再次发起请求,本章将此称为"客户端重定向".既然有客户端重定向,自然就有服务端重定向 ...
- @SuppressWarnings注解的使用
Java编译器在编译代码时,会产生一些安全警告信息.如果被@SuppressWarnings注解标记的元素,就可以告诉编译器抑制指定的警告. 先看看@SuppressWarnings注解在Java S ...
- CF1817E Half-sum 另解与 Trygub Number
一题水两篇怎么说. 上一篇中我们采用智慧方法减少了比较次数,避免了使用复杂的高精度数.现在我们有高论!可以做到 \(\mathrm O(\log_B V\log_2 n)\) 在某一位加或者减一个大小 ...
- GPT3与机器翻译的结合:探索新的语言翻译技术
目录 引言 随着全球化的加速和人工智能的快速发展,机器翻译成为了许多企业.机构和个人的痛点.虽然已有多种机器翻译技术,但基于自然语言处理和深度学习的机器翻译一直缺乏有效的解决方案,这导致机器翻译的准确 ...
- prometheus Histogram 统计原理
大家好,我是蓝胖子,书接上文,我在prometheus描点原理那一篇文章里,留了一个思考题: 我们通常会用到histogram_quantile去计算服务接口时间的耗时情况. histogram_qu ...