【websocket】使用案例( JSR 356 标准)
目录
一、JSR 356方式:简单示例
1、引入依赖
2、注册端点扫描器
3、编写通过注解处理生命周期和消息
4、细节解读
5、总结
二、聊天室案例
方案流程
1、引入依赖
2、注册端点扫描器
3、编写一个配置类,读取httpsession
4、编写通过注解处理生命周期和消息,并且读取到配置类
5、读取配置文件
6、OnOpen方法,获取httpsession
7、OnMessage方法
8、OnClose方法
大家好,我是jstart千语。在上一篇已经讲了Spring原生底层API的实现方式,这一篇我们讲解JSR 356 标准的实现方式。
Spring原生底层API的使用方式:【webSocket协议】进阶实战案例(Spring 原生低层 API)-CSDN博客
一、JSR 356方式:简单示例
实现流程:
- 引入依赖
- 注册端点扫描器
- 编写通过注解处理生命周期和消息
1、引入依赖
<!-- websocket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
2、注册端点扫描器
@Configuration
public class Jsr356Config {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter(); // 扫描 @ServerEndpoint 注解类}
}
3、编写通过注解处理生命周期和消息
@Component //便于后续注入spring容器的bean
@ServerEndpoint("/jsr-ws") // 连接路径
public class Jsr356Endpoint {//注意要使用静态变量private static Map<Session, String> sessions = new ConcurrentHashMap<>();private static UserService userService; // 静态变量解决依赖注入问题// 通过 setter 注入 Spring Bean@Autowiredpublic void setUserService(UserService userService) {Jsr356Endpoint.userService = userService;}@OnOpenpublic void onOpen(Session session) {sessions.put(session, "User-" + session.getId());}@OnMessagepublic void onMessage(Session session, String message) {userService.logMessage(message); // 使用注入的 Beansessions.forEach((s, username) -> {s.getAsyncRemote().sendText("收到消息: " + message);});}@OnClosepublic void onClose(Session session) {sessions.remove(session);}
}
4、细节解读
- @ServerEndpoint 注解的类由 WebSocket 容器(如 Tomcat、Jetty)直接实例化,而不是通过 Spring 容器创建。因此,Spring 的依赖注入(如 @Autowired)在普通成员变量上无法生效。
- 由于每个 WebSocket 连接都会创建一个新的 @ServerEndpoint 实例,若想在这些实例之间共享同一个 Spring Bean(如 UserService),必须通过 静态变量 持有该 Bean 的引用。
实现机制:
1、静态 set 方法:
Spring 在启动时会扫描所有被 @Component 注解的类,并处理其中的 @Autowired 注解。通过在静态 set 方法上添加 @Autowired,Spring 会调用该方法将 Bean 注入到静态变量中。
2、注入时机:
Spring 在初始化 Jsr356Endpoint 类时,发现该静态 set 方法,并将 UserService Bean 赋值给静态变量。这样所有 @ServerEndpoint 实例都能共享同一个 Bean。
5、总结
- 静态 set 方法 + @Autowired 是为了绕过 @ServerEndpoint 类无法由 Spring 直接管理的问题,强制注入 Spring Bean。
- 本质是一种变通方案,并非 Spring 的标准用法,需谨慎处理线程安全和初始化顺序问题。
- 优先使用 STOMP,减少对底层 WebSocket API 的直接操作。
二、聊天室案例
方案流程
- 引入依赖
- 注册端点扫描器
- 编写一个配置类,读取httpsession
- 编写通过注解处理生命周期和消息,并且读取到配置类
- 新用户连接到来,在open方法广播消息给聊天室其他用户
- 用户给另一个用户发消息时,走OnMessage方法,向指定用户发送消息
- 用户断开连接,广播消息,通知该用户下线
1、引入依赖
<!-- websocket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
2、注册端点扫描器

3、编写一个配置类,读取httpsession

4、编写通过注解处理生命周期和消息,并且读取到配置类
这里就会在websocket通信前完成,可以从request中获取session,并且在重写方法的形参中的sec参数间接传入session,这样在后续的OnOpen、OnMessage、OnClose方法中使用到httpsession啦。

5、读取配置文件
直接在消息处理类的上面@ServerEndpoint注解里面添加一个属性,并指定要读取的配置文件即可

6、OnOpen方法,获取httpsession
可以在连接建立时,也就是OnOpen方法中,就将httpsession获取出来,然后赋值给一个类的成员变量,这样接下来的其他方法也可以共同读取了,不用反复获取httpsession。
(1)首先我们明确httpsession里面存的是什么

(2)从OnOpen的形参中获取配置文件中已经放入websocket的session的值:

(3)OnOpen完整方法(广播消息)

7、OnMessage方法

8、OnClose方法

相关文章:
【websocket】使用案例( JSR 356 标准)
目录 一、JSR 356方式:简单示例 1、引入依赖 2、注册端点扫描器 3、编写通过注解处理生命周期和消息 4、细节解读 5、总结 二、聊天室案例 方案流程 1、引入依赖 2、注册端点扫描器 3、编写一个配置类,读取httpsession 4、编写通过注解处理生…...
tcpdump`是一个非常强大的命令行工具,用于在网络上捕获并分析数据包
通过 tcpdump,你可以抓取网络流量,诊断网络问题,或分析通信协议的细节。下面是如何在 Linux 上使用 tcpdump 进行抓包的详细步骤。 1. 安装 tcpdump 在大多数 Linux 发行版中,tcpdump 是默认安装的。如果没有安装,可…...
IS-IS中特殊字段——OL过载
文章目录 OL 过载位 🏡作者主页:点击! 🤖Datacom专栏:点击! ⏰️创作时间:2025年04月13日20点12分 OL 过载位 路由过载 使用 IS-IS 的过载标记来标识过载状态 对设备设置过载标记后ÿ…...
【时频谱分析】快速谱峭度
算法配置页面,也可以一键导出结果数据 报表自定义绘制 获取和下载【PHM学习软件PHM源码】的方式 获取方式:Docshttps://jcn362s9p4t8.feishu.cn/wiki/A0NXwPxY3ie1cGkOy08cru6vnvc...
Spring Boot 支持的内嵌服务器(Tomcat、Jetty、Undertow、Netty(用于 WebFlux 响应式应用))详解
Spring Boot 支持的内嵌服务器详解 1. 支持的内嵌服务器 Spring Boot 默认支持以下内嵌服务器: Tomcat(默认)JettyUndertowNetty(用于 WebFlux 响应式应用) 2. 各服务器使用示例 (1) Tomcat(默认…...
微软Exchange管理中心全球范围宕机
微软已确认Exchange管理中心(Exchange Admin Center,EAC)发生全球性服务中断,导致管理员无法访问关键管理工具。该故障被标记为关键服务事件(编号EX1051697),对依赖Exchange Online的企业造成广…...
基于AI的Web应用防火墙(AppWall)实战:漏洞拦截与威胁情报集成
摘要:针对Web应用面临的OWASP、CVE等漏洞攻击,本文结合群联AI云防护系统的AppWall模块,详解AI规则双引擎的防御原理,并提供漏洞拦截配置与威胁情报集成代码示例。 一、Web应用安全挑战与AppWall优势 传统WAF依赖规则库更新滞后&a…...
基于Qt的串口通信工具
程序介绍 该程序是一个基于Qt的串口通信工具,专用于ESP8266 WiFi模块的AT指令配置与调试。主要功能包括: 1. 核心功能 串口通信:支持串口开关、参数配置(波特率、数据位、停止位、校验位)及数据收发。 AT指令操作&a…...
CSS 字体学习笔记
在网页设计中,字体的使用对于提升用户体验和页面美观性至关重要。CSS 提供了一系列字体属性,用于控制文本的显示效果。以下是对 CSS 字体属性的详细学习笔记。 一、字体系列(font-family) 1. 字体系列的分类 在 CSS 中…...
《MySQL是怎样运行的》总结笔记
内容太多,主要总结一些自己认为重要的,另外太基础常见可能不会总结上。 字符集和比较规则 MySQL会通过把字符串编码后再进行比较大小并排序,有一些很早的字符集可能会不支持中文,比如ASCII、ISO 8859-1,现在最常用的…...
力扣每日打卡 1922. 统计好数字的数目 (中等)
力扣 1922. 统计好数字的数目 中等 前言一、题目内容二、解题方法1. 暴力解法(会超时,此法不通)2. 快速幂运算3. 组合计数的思维逻辑分析组合计数的推导例子分析思维小结论 4.官方题解4.1 方法一:快速幂 三、快速幂运算快速幂运算…...
上层 Makefile 控制下层 Makefile 的方法
在复杂的项目中,通常会将项目划分为多个模块或子项目,每个模块都有自己的 Makefile。上层 Makefile 的作用是协调和控制这些下层 Makefile 的构建过程。下面是几种常见的示例,实现上层 Makefile 对下层 Makefile 的控制。 直接调用࿱…...
html简易实现推箱子小游戏原理(易上手)
实现效果 使用方向键移动,将橙色箱子推到绿色目标区域(黑色块为墙,白色块为可通过区域,蓝球为小人) 实现过程 <!DOCTYPE html> <html> <head><title>推箱子小游戏</title><style&g…...
搭建一个Spring Boot聚合项目
1. 创建父项目 打开IntelliJ IDEA,选择 New Project。 在创建向导中选择 Maven,确保选中 Create from archetype,选择 org.apache.maven.archetypes:maven-archetype-quickstart。 填写项目信息: GroupId:com.exampl…...
字符串与栈和队列-算法小结
字符串 双指针 反转字符串(双指针) 力扣题目链接 void reverseString(vector<char>& s) {for (int i 0, j s.size() - 1; i < s.size()/2; i, j--) {swap(s[i],s[j]);} }反转字符串II 力扣题目链接 遍历字符串的过程中,只要让 i (2 * k)&#…...
类似东郊到家的上门按摩预约服务系统小程序APP源码全开源
🔥 为什么上门按摩正在席卷全国? 万亿蓝海市场爆发 2024年中国按摩市场规模突破8000亿,上门服务增速达65% 90后成消费主力,**72%**白领每月至少使用1次上门按摩(数据来源:艾媒咨询) 传统痛点…...
Python | 在Pandas中按照中值对箱形图排序
箱形图是可视化数据分布的强大工具,因为它们提供了对数据集内的散布、四分位数和离群值的洞察。然而,当处理多个组或类别时,通过特定的测量(如中位数)对箱形图进行排序可以提高清晰度并有助于揭示模式。在本文中&#…...
[实战] 二分查找与哈希表查找:原理、对比与C语言实现(附完整C代码)
二分查找与哈希表查找:原理、对比与C语言实现 一、引言 在计算机科学中,高效的数据查找是核心问题之一。本文深入解析两种经典查找算法:二分查找与哈希表查找,从算法原理、时间复杂度、适用场景到完整C语言实现,提供…...
游戏引擎学习第215天
总结并为今天做铺垫 今天的工作内容是解决调试系统中的一个小问题。昨天我们已经完成了大部分的调试系统工作,但还有一个小部分没有完全处理,那就是关于如何层次化组织数据的问题。我们遇到的一个问题是,演示代码中仍有一个尚未解决的部分&a…...
【Redis】redis事物与管道
Redis 事务(Transaction) 事务概念 事务:是一组操作的集合,是不可分割的工作单元。Redis 事务特点: 一个事务可以一次执行多个命令。所有命令都被顺序化,形成一个队列。所有命令在执行 EXEC 时一次性、顺…...
Django信号使用完全指南示例
推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 **引言:****先决条件:****目录:****1. 什么是Django信号?****2:设置你的Django项目****2.1. 安装Django**2.2. 创建一个Django项…...
DeepSeek BLEU和ROUGE(Recall)的计算
以下是 BLEU Score (Bilingual Evaluation Understudy)和 ROUGE Score(Recall-Oriented Understudy for Gisting Evaluation) 的原生Python实现(不依赖第三方库),通过分步计算逻辑和示例详细说明。 一、BLEU Score 实现 核心逻辑…...
vulkanscenegraph显示倾斜模型(5.9)-vsg中vulkan资源的编译
前言 上一章深入剖析了GPU资源内存及其管理,vsg中为了提高设备内存的利用率,同时减少内存(GPU)碎片,采用GPU资源内存池机制(vsg::MemoryBufferPools)管理逻辑缓存(VkBuffer)与物理内存(VkDeviceMemory)。本章将深入vsg中vulkan资源的编译(包含…...
今日行情明日机会——20250409
今日行情还需要考虑关税对抗~ 2025年4月8日涨停的主要行业方向分析 1. 军工(19家涨停) 细分领域:国防装备、航空航天、军民融合。催化因素:国家安全战略升级、国防预算增加、重大军工项目落地预期。 2. 免税(15家涨…...
XHR、FetchAxios详解网络相关大片文件上传下载
以下是 XHR(XMLHttpRequest) 与 Fetch API 的全面对比分析,涵盖语法、功能、兼容性等核心差异: 一、语法与代码风格 XHR(基于事件驱动) 需要手动管理请求状态(如 onreadystatechange 事件)和错误处理,代码冗长且易出现回调地狱。 const xhr = new XMLHttpRequest(); x…...
Python基础总结(四)之元组
文章目录 一、元组格式二、元组操作2.1 转换元组 与 列表一样,元组也是序列,唯一的区别在于元组是不能修改的,与字符串一样。 一、元组格式 元组的创建方式很简单,秩序用逗号将元素隔开就能自动创建一个元组 示例: …...
系统分析师(六)-- 计算机网络
概述 TCP/IP 协议族 DNS DHCP 网络规划与设计 逻辑网络设计 物理网络设计 题目 层次化网络设计 网络冗余设计 综合布线系统 IP地址 网络接入技术 其他网络技术应用 物联网...
【前端】【React】useCallback的作用与使用场景总结
一、useCallback 的作用与使用场景总结 useCallback 是 React 提供的一个 Hook,用于缓存函数的引用,避免因为组件重新渲染而导致函数地址发生变化。它返回一个记忆(memoized)后的回调函数,只有当依赖项发生变化时才会…...
Qwen2.5-VL Technical Report 论文翻译和理解
一、TL;DR Qwen2.5-VL是QwenVL的最新模型,在视觉识别、精准目标定位、稳健文档解析以及长视频理解等方面实现了重大突破引入了动态分辨率处理和绝对时间编码,使其能够处理不同尺寸的图像以及长达数小时的视频,并实现秒级事件定位…...
Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析
Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析 漏洞背景 漏洞编号:CNVD-2025-06036 CVE编号:待分配 厂商:腾讯Foxmail 影响版本:Foxmail < 7.2.25 漏洞类型&#x…...
