当前位置: 首页 > article >正文

SpringBoot3整合WebSocket

一、WebSocket简介

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信,允许服务器主动向客户端推送数据。
与传统的 HTTP 请求-响应模式不同,WebSocket 在建立连接后,允许服务器和客户端之间进行双向实时通信。

WebSocket主要特点:

  • 建立在 TCP 协议之上。
  • 与 HTTP 协议有着良好的兼容性。
  • 数据格式比较轻量,性能开销小,通信高效。
  • 可以发送文本,也可以发送二进制数据。
  • 没有同源限制,客户端可以与任意服务器通信。
  • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

二、SpringBoot3集成WebSocket

引入 WebSocket依赖:

        <!-- WebSocket依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>3.4.5</version></dependency>

1、WebSocket配置类

创建 WebSocket 配置类,启用 WebSocket 功能并注册端点。

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Autowiredprivate CustomTextWebSocketHandler customTextWebSocketHandler;@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {/*** addHandler方法参数说明* 参数1:添加 WebSocket 处理器* 参数2:WebSocket的连接路径、端口为项目端口、路径为自定义。比如:URL = ws://127.0.0.1:38081/ws*/registry.addHandler(customTextWebSocketHandler, "/ws").setAllowedOrigins("*"); // 允许跨域访问}}

2、自定义WebSocket处理器

创建自定义的 WebSocket 处理器,处理消息收发。

@Slf4j
@Component
@RequiredArgsConstructor
public class CustomTextWebSocketHandler extends TextWebSocketHandler {private final WebSocketSessionManager sessionManager;/*** 用于存储WebSocket会话*/private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {String sessionId = session.getId();sessionManager.add(session);log.info("WebSocket连接建立成功:{}", sessionId);}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {String payload = message.getPayload();log.info("WebSocket收到消息 ==> sessionId = {}, payload = {} ", session.getId(), message.getPayload());boolean open = session.isOpen();if (!open) {log.info("WebSocket发送消息失败 ==> sessionId = {} 不在线 ", session.getId());return;}try {/*** TODO 发送回复消息*/String replyMessage = "服务器 -> 客户端 收到了,消息" + payload;session.sendMessage(new TextMessage(replyMessage));} catch (IOException e) {log.info("WebSocket发送消息异常 ==> sessionId = {}, e = ", session.getId(), e);}}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {log.info("WebSocket传输错误 ==> sessionId = {}, exception = {} ", session.getId(), exception.getMessage());// 传输错误,关闭连接this.afterConnectionClosed(session, CloseStatus.PROTOCOL_ERROR);}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {log.info("WebSocket连接关闭 ==> sessionId = {}, CloseStatus = {} ", session.getId(), status);sessionManager.remove(session);}/*** 广播发送消息给所有连接的 WebSocket客户端** @param message*/public void sendMessageByBroadcast(String message) {sessionManager.getAllSession().stream().filter(WebSocketSession::isOpen).forEach(session -> {try {session.sendMessage(new TextMessage(message));} catch (IOException e) {log.info("WebSocket 广播发送消息异常 ==> sessionId = {}, e = ", session.getId(), e);}});}}

3、创建WebSocket会话管理类

自定义创建 WebSocket会话管理类,根据业务我们可以扩展存储不同的信息。

@Slf4j
@Component
public class WebSocketSessionManager {/*** 用于存储 WebSocket会话* key: sessionId* value: WebSocketSession*/private final Map<String, WebSocketSession> wsSessionMap = new ConcurrentHashMap<>();/*** 添加 WebSocket会话** @param session*/public void add(WebSocketSession session) {wsSessionMap.put(session.getId(), session);}/*** 移除 WebSocket会话** @param session*/public void remove(WebSocketSession session) {wsSessionMap.remove(session.getId());}/*** 获取 WebSocket会话** @param sessionId* @return*/public WebSocketSession get(String sessionId) {return wsSessionMap.get(sessionId);}/*** 获取所有 WebSocket会话*/public List<WebSocketSession> getAllSession() {Collection<WebSocketSession> sessions = wsSessionMap.values();return Optional.ofNullable(sessions).orElse(new ArrayList<>()).stream().toList();}
}

4、controller

创建测试controller,用来测试消息广播。

@RestController
@RequestMapping("/api/wsTest")
@RequiredArgsConstructor
public class WSTestController {private final CustomTextWebSocketHandler customTextWebSocketHandler;/*** 广播发送消息接口* 给所有连接的 WebSocket 客户端** @param message* @return*/@GetMapping("/sendMessageByBroadcast")public ResponseEntity<String> sendMessageByBroadcast(@RequestParam("message") String message) {customTextWebSocketHandler.sendMessageByBroadcast(message);return ResponseEntity.ok("广播发送消息接口 => 发送成功");}}

启动项目,使用 WebSocket 在线测试工具等,测试ok。

WebSocket 在线测试工具:https://wstool.js.org/

在这里插入图片描述

根据业务还可以自定义握手拦截器校验token,配置最大闲置时间,比如3分钟没动自动关闭连接等配置。

在这里插入图片描述

– 求知若饥,虚心若愚。

http://www.lryc.cn/news/2384878.html

相关文章:

  • 鸿蒙进阶——驱动框架UHDF 机制核心源码解读(一)
  • 电子电路:能认为电抗也是在做功吗?
  • DEEPSEEK + 其他工具的玩法
  • Idea 配合 devtools 依赖 实现热部署
  • 远程访问家里的路由器:异地访问内网设备或指定端口网址
  • 根据参数量,如何推断需要多少数据才能够使模型得到充分训练?
  • PycharmFlask 学习心得:路由(3-4)
  • 从逻辑学视角严谨证明数据加密的数学方法与实践
  • 敦煌网测评从环境搭建到风控应对,精细化运营打造安全测评体系
  • 现代化SQLite的构建之旅——解析开源项目Limbo
  • 本地分支git push 报错 fatal: The current branch XXXX has no upstream branch.
  • 人工智能100问☞第27问:神经网络与贝叶斯网络的关系?
  • Python----循环神经网络(WordEmbedding词嵌入)
  • ElasticSearch各种查询语法示例
  • CUDA的设备,流处理器(Streams),核,线程块(threadblock),线程,网格(‌gridDim),块(block)和多gpu设备同步数据概念
  • PyTorch的dataloader制作自定义数据集
  • LeetCode 1340. 跳跃游戏 V(困难)
  • x-cmd install | cargo-selector:优雅管理 Rust 项目二进制与示例,开发体验升级
  • 数据库设计文档撰写攻略
  • Python爬虫(10)Python数据存储实战:基于pymongo的MongoDB开发深度指南
  • 大模型「瘦身」指南:从LLaMA到MobileBERT的轻量化部署实战
  • 从逻辑视角学习信息论:概念框架与实践指南
  • springboot配置mysql druid连接池,以及连接池参数解释
  • Spring Boot集成Resilience4j实现微服务容错机制
  • (一) 本地hadoop虚拟机系统设置
  • TDengine 运维—容量规划
  • 【MySQL成神之路】MySQL索引相关介绍
  • PPP 拨号失败:ATD*99***1# ... failed
  • PostgreSQL跨数据库表字段值复制实战经验分
  • 【计网】五六章习题测试