一、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.pswp.cn/web/80993.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/80993.shtml
英文地址,请注明出处:http://en.pswp.cn/web/80993.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FTP Bounce Attack:原理、影响与防御

一、引言 FTP&#xff08;文件传输协议&#xff09;是一种用于在网络上进行文件传输的协议&#xff0c;广泛应用于各种网络环境中。然而&#xff0c;FTP协议的安全性问题一直备受关注&#xff0c;其中FTP Bounce Attack&#xff08;FTP跳转攻击&#xff09;是一种具有代表性的…

文献阅读——NeuroBayesSLAM

原文地址 1.核心理论&#xff1a;贝叶斯多感官整合框架 目标&#xff1a;结合视觉线索 c v i c_{vi} cvi​和前庭线索 c v e c_{ve} cve​来估计头部方向或位置 θ 贝叶斯公式 p ( θ ∣ c v i , c v e ) ∝ p ( c v i ∣ θ ) p ( c v e ∣ θ ) p ( θ ) p(\theta | c_{vi…

sentinel核心原理-高频问题

核心原理 ‌限流实现机制‌ ‌滑动窗口算法‌&#xff1a;将时间切分为子窗口动态统计QPS&#xff0c;避免固定窗口的边界问题。‌责任链模式‌&#xff1a;通过NodeSelectorSlot、FlowSlot等Slot链式处理限流逻辑。 ‌熔断降级策略‌ ‌慢调用比例‌&#xff1a;当慢请求比例…

DataX 的大概简单介绍(与Kettle做对比介绍)

DataX 是由阿里巴巴开源的轻量级 ETL 工具&#xff0c;专为批量数据同步设计&#xff0c;主打 “高性能、易扩展、跨数据源”。如果你熟悉 Kettle&#xff0c;可把它理解为 “更适合大数据场景的 ETL 选手”。以下从核心特性、应用场景、与 Kettle 对比等角度通俗解析&#xff…

通过上传使大模型读取并分析文件实战

一、技术背景与需求分析 我们日常在使用AI的时候一定都上传过文件&#xff0c;AI会根据用户上传的文件内容结合用户的请求进行分析&#xff0c;给出用户解答。但是这是怎么实现的呢&#xff1f;在我们开发自己的大模型应用时肯定是不可避免的要思考这个问题&#xff0c;今天我会…

RHCSA Linux 系统 硬盘管理

Linux 系统 硬盘管理 1扇区 512B&#xff0c;分区 多个扇区 512B 查看硬盘命令 [rootlocalhost ~]# lsblk 1.一般存储相关操作 (1) 分区 ① MBR 分区 ➤分区数量限制&#xff1a;主分区 0 - 4 个&#x…

计算机网络——Session、Cookie 和 Token

在 Web 开发中&#xff0c;Session、Cookie 和 Token 是实现用户会话管理和身份验证的核心技术。它们既有联系&#xff0c;也有明显区别。以下从定义、原理、联系、区别和应用场景等方面详细解析。 一、基本定义与原理 1. Cookie 定义&#xff1a; 是浏览器存储在客户端的小…

双均线量化交易策略指南

策略原理 采用两条不同周期的简单移动平均线&#xff08;SMA&#xff09;&#xff1a; 短期均线&#xff1a;5日线&#xff08;快速反应价格变化&#xff09;长期均线&#xff1a;20日线&#xff08;反映长期趋势&#xff09; 交易信号生成规则&#xff1a; 当 5日线 > …

视频太大?用魔影工厂压缩并转MP4,画质不打折!

在日常生活中&#xff0c;我们常常需要将视频文件转换成不同的格式以适应各种设备或平台的播放需求。魔影工厂作为一款功能强大且操作简单的视频转换工具&#xff0c;深受用户喜爱。本文中简鹿办公将手把手教你如何使用魔影工厂将视频转换为MP4格式&#xff0c;并进行个性化设置…

大腾智能 PDM 系统:全生命周期管理重塑制造企业数字化转型路径

在当今激烈的市场竞争中&#xff0c;产品迭代速度与质量已成为企业生存与发展的核心命脉。面对客户需求多元化、供应链协同复杂化、研发成本管控精细化等挑战&#xff0c;企业亟需一套能够贯穿产品全生命周期的数字化解决方案。 大腾智能PDM系统通过构建覆盖设计、研发、生产、…

CodeBuddy一腾讯内部已有超过 85% 的程序员正在使用de编程工具

大家好&#xff0c;我是程序员500佰&#xff0c;目前正在前往独立开发路线&#xff0c;我会在这里分享关于编程技术、独立开发、技术资讯以及编程感悟等内容。 如果本文能给你提供启发和帮助&#xff0c;还请留下你的一健三连&#xff0c;给我一些鼓励&#xff0c;谢谢。 本文直…

解锁 Zblog 资讯系统:502 错误修复与双域名适配的实战秘籍

在网络世界的激烈竞争中&#xff0c;资讯类网站如同战场上的士兵&#xff0c;每一次页面加载、每一次内容展示都关乎着用户的留存与转化。而 Zblog 作为备受青睐的资讯系统&#xff0c;承载着众多站长的流量梦想。然而&#xff0c;在网站运营过程中&#xff0c;502 错误页面的突…

今日打卡,Leetcode第四题:寻找两个正序数组的中位数,博主表示就会sorted

4. 寻找两个正序数组的中位数 博主只会第一个暴力解法&#xff0c;然后将官网上的源码上添加些注释&#xff0c;尝试理解&#xff0c;分下今日刷题记录 题目描述 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个…

Jouier 普及组十连测 R3

反思 首先&#xff0c;先悔恨一下这次的比赛成绩。 这次比赛的教训就是&#xff0c;简单的题目一定要打不要被复杂的题面震慑到&#xff0c;以及变量名不能是保留字&#xff0c;如第一题的x1,y1&#xff0c;要开long long&#xff0c;计算好数据范围&#xff0c;如第三第四题。…

Open CASCADE学习|非线性方程组求解技术详解

引言 在几何建模与工程计算中&#xff0c;非线性方程组的求解是常见的核心问题。Open CASCADE&#xff08;以下简称OCC&#xff09;作为开源的几何建模内核&#xff0c;提供了丰富的数学工具库&#xff0c;其中math_FunctionSetRoot类专为求解非线性方程组设计。本文将深入探讨…

科技初创企业创新推动商业未来

在这个因变革而蓬勃发展的世界里&#xff0c;科技初创企业已成为各行业创新、颠覆与转型的驱动力。这些雄心勃勃的企业正在重塑商业格局&#xff0c;挑战既定规范&#xff0c;并不断突破可能性的边界。本文将深入探索科技初创企业的精彩领域&#xff0c;探讨它们如何通过创新塑…

霍尼韦尔HMR2300-D00-485数字模块

型号&#xff1a;HMR2300-D00-485 类型&#xff1a;数字通信模块&#xff08;RS-485接口&#xff09; 制造商&#xff1a;霍尼韦尔&#xff08;Honeywell&#xff09;&#xff0c;隶属于其工业自动化或楼宇自动化产品线。 典型用途&#xff1a; 用于扩展主控制器&#xff08;如…

如何在 Windows 11 或 10 上更改 WIFI 或以太网 MAC 地址?

无论你使用的是哪种操作系统,更改 MAC 地址在各种场景中都有其益处。每个网卡的 MAC 地址都是唯一的,由网络适配器在出厂时就已经分配完成;它帮助系统在物理网络上进行通信,并为其提供身份识别。然而,如果你出于某种合法原因想要更改 Windows 上的当前 MAC 地址,那么我们…

Python语法特点与编码规范

注释 单行注释 把#号当做注释符号 多行注释 python中并没有规定多行注释标记&#xff0c;通常使用单引号作为多行注释 中文注释 规定文件所用编码&#xff0c;当时是为解决python2不支持中文的问题 #codingutf-8代码缩进 python采用代码缩进和冒号区分代码层次&#xff0c…

跟Gemini学做PPT:字号选择

字号的选择对于 PPT 的可读性和视觉效果至关重要。以下是一些通用的建议和针对你具体情况的字号选择指南&#xff1a; 通用字号选择原则&#xff1a; 对比度&#xff1a; 文字颜色与背景颜色形成高对比度&#xff0c;确保易读。字体&#xff1a; 选择清晰、专业的字体&#x…