【websocket】使用案例( ​JSR 356 标准)

news2025/5/16 1:29:19

目录

一、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. 引入依赖
  2. 注册端点扫描器
  3. 编写通过注解处理生命周期和消息

1、引入依赖

        <!-- websocket -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

2、注册端点扫描器

@Configuration
public class Jsr356Config {
    @Bean
    public 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
    @Autowired
    public void setUserService(UserService userService) {
        Jsr356Endpoint.userService = userService;
    }

    @OnOpen
    public void onOpen(Session session) {
        sessions.put(session, "User-" + session.getId());
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        userService.logMessage(message);  // 使用注入的 Bean
        sessions.forEach((s, username) -> {
            s.getAsyncRemote().sendText("收到消息: " + message);
        });
    }

    @OnClose
    public 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 的直接操作。

二、聊天室案例

方案流程

  1. 引入依赖
  2. 注册端点扫描器
  3. 编写一个配置类,读取httpsession
  4. 编写通过注解处理生命周期和消息,并且读取到配置类
  • 新用户连接到来,在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方法 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334679.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IS-IS中特殊字段——OL过载

文章目录 OL 过载位 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Datacom专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年04月13日20点12分 OL 过载位 路由过载 使用 IS-IS 的过载标记来标识过载状态 对设备设置过载标记后&#xff…

【时频谱分析】快速谱峭度

算法配置页面&#xff0c;也可以一键导出结果数据 报表自定义绘制 获取和下载【PHM学习软件PHM源码】的方式 获取方式&#xff1a;Docshttps://jcn362s9p4t8.feishu.cn/wiki/A0NXwPxY3ie1cGkOy08cru6vnvc

Spring Boot 支持的内嵌服务器(Tomcat、Jetty、Undertow、Netty(用于 WebFlux 响应式应用))详解

Spring Boot 支持的内嵌服务器详解 1. 支持的内嵌服务器 Spring Boot 默认支持以下内嵌服务器&#xff1a; Tomcat&#xff08;默认&#xff09;JettyUndertowNetty&#xff08;用于 WebFlux 响应式应用&#xff09; 2. 各服务器使用示例 (1) Tomcat&#xff08;默认&#xf…

微软Exchange管理中心全球范围宕机

微软已确认Exchange管理中心&#xff08;Exchange Admin Center&#xff0c;EAC&#xff09;发生全球性服务中断&#xff0c;导致管理员无法访问关键管理工具。该故障被标记为关键服务事件&#xff08;编号EX1051697&#xff09;&#xff0c;对依赖Exchange Online的企业造成广…

基于Qt的串口通信工具

程序介绍 该程序是一个基于Qt的串口通信工具&#xff0c;专用于ESP8266 WiFi模块的AT指令配置与调试。主要功能包括&#xff1a; 1. 核心功能 串口通信&#xff1a;支持串口开关、参数配置&#xff08;波特率、数据位、停止位、校验位&#xff09;及数据收发。 AT指令操作&a…

html简易实现推箱子小游戏原理(易上手)

实现效果 使用方向键移动&#xff0c;将橙色箱子推到绿色目标区域&#xff08;黑色块为墙&#xff0c;白色块为可通过区域&#xff0c;蓝球为小人&#xff09; 实现过程 <!DOCTYPE html> <html> <head><title>推箱子小游戏</title><style&g…

字符串与栈和队列-算法小结

字符串 双指针 反转字符串(双指针) 力扣题目链接 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 力扣题目链接 遍历字符串的过程中&#xff0c;只要让 i (2 * k)&#…

类似东郊到家的上门按摩预约服务系统小程序APP源码全开源

&#x1f525; 为什么上门按摩正在席卷全国&#xff1f; 万亿蓝海市场爆发 2024年中国按摩市场规模突破8000亿&#xff0c;上门服务增速达65% 90后成消费主力&#xff0c;**72%**白领每月至少使用1次上门按摩&#xff08;数据来源&#xff1a;艾媒咨询&#xff09; 传统痛点…

Python | 在Pandas中按照中值对箱形图排序

箱形图是可视化数据分布的强大工具&#xff0c;因为它们提供了对数据集内的散布、四分位数和离群值的洞察。然而&#xff0c;当处理多个组或类别时&#xff0c;通过特定的测量&#xff08;如中位数&#xff09;对箱形图进行排序可以提高清晰度并有助于揭示模式。在本文中&#…

游戏引擎学习第215天

总结并为今天做铺垫 今天的工作内容是解决调试系统中的一个小问题。昨天我们已经完成了大部分的调试系统工作&#xff0c;但还有一个小部分没有完全处理&#xff0c;那就是关于如何层次化组织数据的问题。我们遇到的一个问题是&#xff0c;演示代码中仍有一个尚未解决的部分&a…

【Redis】redis事物与管道

Redis 事务&#xff08;Transaction&#xff09; 事务概念 事务&#xff1a;是一组操作的集合&#xff0c;是不可分割的工作单元。Redis 事务特点&#xff1a; 一个事务可以一次执行多个命令。所有命令都被顺序化&#xff0c;形成一个队列。所有命令在执行 EXEC 时一次性、顺…

Django信号使用完全指南示例

推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 **引言:****先决条件:****目录:****1. 什么是Django信号?****2:设置你的Django项目****2.1. 安装Django**2.2. 创建一个Django项…

vulkanscenegraph显示倾斜模型(5.9)-vsg中vulkan资源的编译

前言 上一章深入剖析了GPU资源内存及其管理&#xff0c;vsg中为了提高设备内存的利用率&#xff0c;同时减少内存(GPU)碎片&#xff0c;采用GPU资源内存池机制(vsg::MemoryBufferPools)管理逻辑缓存(VkBuffer)与物理内存(VkDeviceMemory)。本章将深入vsg中vulkan资源的编译(包含…

今日行情明日机会——20250409

今日行情还需要考虑关税对抗~ 2025年4月8日涨停的主要行业方向分析 1. 军工&#xff08;19家涨停&#xff09; 细分领域&#xff1a;国防装备、航空航天、军民融合。催化因素&#xff1a;国家安全战略升级、国防预算增加、重大军工项目落地预期。 2. 免税&#xff08;15家涨…

系统分析师(六)-- 计算机网络

概述 TCP/IP 协议族 DNS DHCP 网络规划与设计 逻辑网络设计 物理网络设计 题目 层次化网络设计 网络冗余设计 综合布线系统 IP地址 网络接入技术 其他网络技术应用 物联网

Qwen2.5-VL Technical Report 论文翻译和理解

一、TL&#xff1b;DR Qwen2.5-VL是QwenVL的最新模型&#xff0c;在视觉识别、精准目标定位、稳健文档解析以及长视频理解等方面实现了重大突破引入了动态分辨率处理和绝对时间编码&#xff0c;使其能够处理不同尺寸的图像以及长达数小时的视频&#xff0c;并实现秒级事件定位…

Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析

Foxmail邮件客户端跨站脚本攻击漏洞&#xff08;CNVD-2025-06036&#xff09;技术分析 漏洞背景 ‌漏洞编号‌&#xff1a;CNVD-2025-06036 ‌CVE编号‌&#xff1a;待分配 ‌厂商‌&#xff1a;腾讯Foxmail ‌影响版本‌&#xff1a;Foxmail < 7.2.25 ‌漏洞类型‌&#x…

高并发内存池(三):PageCache(页缓存)的实现

前言&#xff1a; 在前两期内容中&#xff0c;我们深入探讨了内存管理机制中在 ThreadCache 和 CentralCache两个层级进行内存申请的具体实现。这两层缓存作为高效的内存分配策略&#xff0c;能够快速响应线程的内存需求&#xff0c;减少锁竞争&#xff0c;提升程序性能。 本期…

Linux驱动开发-网络设备驱动

Linux驱动开发-网络设备驱动 一&#xff0c;网络设备总体结构1.1 总体架构1.2 NAPI数据处理机制 二&#xff0c;RMII和MDIO2.1 RMII接口2.2 MDIO接口 三&#xff0c;MAC和PHY模块3.1 MAC模块3.2 PHY模块 四&#xff0c;网络模型4.1 网络的OSI和TCP/IP分层模型4.1.1 传输层&…

DataEase同比环比

DataEase同比环比 前言术语实现表结构设计DataEase设计创建数据集创建仪表盘最后前言 某大数据项目,需要比较展示今年跟去年的数据,如下图: 说明:比较24,25的产品销量,相同月份做一组,并排放一块 还有更进一步: 说明:比较24,25相同月份,相同产品的销量 直接用DataE…