spring-boot接入websocket教程以及常见问题解决

news2025/6/5 12:08:35

我们使用spring-boot接入websocket有三种方式:使用@EnableWebSocket@EnableWebSocketMessageBroker以及@ServerEndpoint,本文主要介绍使用@ServerEndpoint方式的流程以及碰到的问题解决

接入方式

添加依赖
确保spring-boot-starter-websocket依赖

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

定义@ServerEndpoint类
这个是核心类方法,可以在这里定义生命周期方法(比如onOpenonMessage等)

//定义成spring bean
@Component
@Slf4j
//定义websocket路径,这里的configurator后面再讲解
@ServerEndpoint(value = "/wss/conn/{cookieValue}",configurator = WebSocketConfigurator.class)
public class WebSocketServer {
    //业务的spring bean注入
    private static TestWrapper testWrapper;

   //静态set注入spring bean
    @Autowired
    public void setTestWrapper(TestWrapper testWrapper) {
        WebSocketServer.testWrapper = testWrapper;
    }

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接建立: " + session.getId());
        //有效性判断,鉴权等
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("收到消息: " + message);
        //收到发送方消息
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("连接关闭: " + session.getId());
    }
}

注册 ServerEndpointExporter(关键!)
Spring Boot 默认不扫描@ServerEndpoint,需通过ServerEndpointExporter将其注册到 WebSocket 容器

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(); // 自动注册 @ServerEndpoint
    }
}

整个配置完成服务启动后(注意websocket的端口可以和自己的spring-web项目用同一个端口,spring会识别是http请求还是websocket请求,自动作对应的映射转发),正常情况能够收发消息

在WebSocketServer如何引用业务spring bean?

我们不能用类似的变量注入@autowire方式来注入我们的业务spring bean,这是因为

  • @ServerEndpoint 实例不是由 Spring 容器管理
    • @ServerEndpoint 标注的类是由 Java EE WebSocket 容器(Tomcat/Undertow)实例化的,不是由 Spring 容器实例化的。
  • Spring 容器不会自动为它注入 @Autowired 的依赖(即使你加了 @Component,也没用)。
    • 虽然加了 @Component,但 WebSocket 实例的生命周期和 Spring Bean 不一致
      Spring 只会管理自己创建的 Bean,WebSocket 容器每次新连接都会 new 一个 WebSocketServer 实例,Spring 不会自动注入依赖

所以,我们可以使用用静态 set 注入,注意:字段要 static,set 方法注入 static 字段。这样 Spring 容器启动时会把 Bean 注入到静态变量,WebSocketServer 的每个实例都能用,类似上述代码中的TestWrapper注入

如何在WebSocketServer建立链接onOpen 获取前端cookie?

我们有的时候会想在websocket建立链接时校验权限,比如校验登录态,这个时候便需要获取前端传递的cookie,WebSocket 的 Session.getUserProperties() 默认并不会自动包含 cookie 信息。对于使用@ServerEndpoint注解的方式

  1. 首先创建一个 ServerEndpointConfig.Configurator 的子类:
public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {

    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        // 获取请求头中的 cookie
        List<String> cookies = request.getHeaders().get("Cookie");
        if (cookies != null && !cookies.isEmpty()) {
            String cookieStr = cookies.get(0);
            Map<String, String> cookieMap = new HashMap<>();

            // 解析 cookie 字符串
            String[] cookieArray = cookieStr.split(";");
            for (String cookie : cookieArray) {
                String[] parts = cookie.trim().split("=");
                if (parts.length == 2) {
                    cookieMap.put(parts[0].trim(), parts[1].trim());
                }
            }
            // 将 cookie 信息存储到 ServerEndpointConfig 的 UserProperties 中
            sec.getUserProperties().put("cookies", cookieMap);
        }
        super.modifyHandshake(sec, request, response);
    }
}
  1. 在WebSocketServer启动类中配置这个Configurator
@Component
@Slf4j
@ServerEndpoint(value = "/wss/conn/{cookieValue}",configurator = WebSocketConfigurator.class)
public class WebSocketServer {
  1. onOpen中获取cookie,进行登录态校验
// 从 Session 的 UserProperties 获取 Cookie
Map<String, String> cookieMap = (Map<String, String>) sessionParam.getUserProperties().get("cookies");
if (MapUtils.isEmpty(cookieMap)) {
 log.warn("WebSocketServer.onOpen no cookies");
 return;
}
String cookie = cookieMap.get("LOGIN_COOKIE_NAME");

服务启动后访问提示Unexpected server response

我们启动服务后访问可能会出现,Unexpected server response: 200等错误,常见错误和原因汇总如下

问题表现原因解决
Unexpected server response: 200路径错误或未注册 WebSocket检查 @ServerEndpoint 路径和 ServerEndpointExporter
Unexpected response code: 404后端路径不存在确保路径与前端一致
Unexpected response code: 500后端代码异常查看服务器日志排查异常

出现诸如200、404等错误,一个点首先确认你的路径是不是对的,建议先用一个最简单的,比如 /wss/test,然后服务启动再测试看,我就是因为路径问题排查了很久,用的路径是一个公共前缀,有很多业务的interceptor和filter都会处理这个前缀开头的路径,导致报错了,没有转到WebSocketServer处理

如何测试验证websocket是否正常

这里推荐一个工具postman,升级到最新版,支持websocket的请求访问,可以调试你的websocket服务是否正常
在这里插入图片描述

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

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

相关文章

迈向分布式智能:解析MCP到A2A的通信范式迁移

智能体与外部世界的桥梁之言&#xff1a; 在深入探讨智能体之间的协作机制之前&#xff0c;我们有必要先厘清一个更基础的问题&#xff1a;**单个智能体如何与外部世界建立连接&#xff1f;** 这就引出了我们此前介绍过的 **MCP&#xff08;Model Context Protocol&…

深度学习|pytorch基本运算-hadamard积、点积和矩阵乘法

【1】引言 pytorch对张量的基本运算和线性代数课堂的教学有一些区别&#xff0c;至少存在hadamard积、点积和矩阵乘法三种截然不同的计算方法。 【2】hadamard积 hadamard积是元素对位相乘&#xff0c;用“*”连接张量&#xff0c;代码&#xff1a; # 导入包 import torch …

FFmpeg移植教程(linux平台)

目录 第三方源码编译三部曲关于 configure 的说明 FFmpeg 移植流程获取源码方法一&#xff1a;git 远程克隆方法二&#xff1a;官网下载压缩包解压 配置安装 第三方源码编译三部曲 Linux平台下有许多开源的第三方库和服务&#xff0c;这些开源代码一般都符合GNU-autotools编码…

Mybatis:灵活掌控SQL艺术

在前面的文章中&#xff0c;小编分享了spring中相关的知识&#xff0c;但是没有分享到&#xff0c;如何去更高效操作数据库。 操作数据库传统的方法就是通过JDBC来进行操作。 这个传统方法使用上可谓是够麻烦的 1.首先创建一个数据源对象 2.设置该数据源的属性&#xff08;…

2025.05.28【Choropleth】群体进化学专用图:区域数据可视化

Load geospatial data Start by loading your geospatial data in R, and build a basic plot. Data from the package The cartography comes with a set of geospatial data included. Learn how to use it to build a choropleth map. 文章目录 Load geospatial dataData …

【春秋云镜】CVE-2022-26965 靶场writeup

知识点 网站的主题或者模块位置一般是可以上传文件的&#xff0c;不过一般为压缩包形式主题或者模块可以上github上找到和cms匹配的源码主题被解压后会放到加入到对应的文件夹中&#xff0c;而且还会自动执行对应的info.php文件(需要主题和cms配套才行)我这里取巧了&#xff0…

JSP、HTML和Tomcat

9x9上三角乘法表 乘法表的实现 <% page contentType"text/html;charsetUTF-8" language"java" %> <!DOCTYPE html> <html> <head><title>99 上三角乘法表</title><style>body {font-family: monospace;padding…

(1)pytest简介和环境准备

1. pytest简介 pytest是python的一种单元测试框架&#xff0c;与python自带的unittest测试框架类似&#xff0c;但是比unittest框架使用起来更简洁&#xff0c;效率更高。根据pytest的官方网站介绍&#xff0c;它具有如下特点&#xff1a; 非常容易上手&#xff0c;入门简单&a…

构建高性能风控指标系统

一、引言 在金融风控领域&#xff0c;指标是风险识别的核心依据。风控平台核心系统之一--规则引擎的运行依赖规则、变量和指标&#xff0c;一个高性能的指标系统非常重要&#xff0c;本文将深入探讨风控平台指标系统的全链路技术实现&#xff0c;涵盖从指标配置到查询优化的完…

晨控CK-UR12与西门子PLC配置Modbus TCP通讯连接操作手册

晨控CK-UR12与西门子PLC配置Modbus TCP通讯连接操作手册 晨控CK-UR12系列作为晨控智能工业级别RFID读写器,支持大部分工业协议如RS232、RS485、以太网。支持工业协议Modbus RTU、Modbus TCP、Profinet、EtherNet/lP、EtherCat以及自由协议TCP/IP等。 本期主题&#xff1a;围绕…

实验一:PyTorch基本操作实验

import torch # PyTorch中初始化矩阵常见有以下几种方法 # 1. 直接使用固定值初始化 # M torch.tensor([[1.0, 2.0, 3.0]]) # 1x3矩阵 # 2. 随机初始化 # M torch.rand(1, 3) # 1x3矩阵&#xff0c;元素在0-1之间均匀分布 # M torch.randn(1, 3) # 1x3矩阵&#xff0c;元…

可视化大屏通用模板Axure原型设计案例

本文将介绍一款基于Axure设计的可视化大屏通用模板&#xff0c;适用于城市、网络安全、园区、交通、社区、工业、医疗、能源等多个领域。 模板概述 这款Axure可视化大屏通用模板集成了多种数据展示模块和组件&#xff0c;旨在为用户提供一个灵活、可定制的数据展示平台。无论…

历年山东大学计算机保研上机真题

历年山东大学计算机保研上机真题 2025山东大学计算机保研上机真题 2024山东大学计算机保研上机真题 2023山东大学计算机保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/school 从1到100找质数 题目描述 从 1 1 1 到 100 100 100 中找出所有的质数。 输入格式 …

Java处理动态的属性:字段不固定、需要动态扩展的 JSON 数据结构

文章目录 引言I `JSONObject` 接收和返回JSONObject 接收和返回数据存储II 签名测试接口dto的定义签名计算III JsonAnySetter 和JsonAnyGetter 注解@JsonAnySetter 的用法@JsonAnyGetter 的用法综合示例引言 应用场景: 签名测试接口、表单配置项、参数列表、插件信息等。技术实…

MAC电脑怎么通过触摸屏打开右键

在Mac电脑上&#xff0c;通过触摸屏打开右键菜单的方法如下&#xff1a; 法1:双指轻点&#xff1a;在触控板上同时用两根手指轻点&#xff0c;即可触发右键菜单。这是Mac上常用的右键操作方法。 法2:自定义触控板角落&#xff1a;可以设置触控板的右下角或左下角作为右键区域…

用 Whisper 打破沉默:AI 语音技术如何重塑无障碍沟通方式?

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

【东枫科技】KrakenSDR 天线阵列设置

标准测向需要五根相同的全向天线。您可以折衷使用更少的天线&#xff0c;但为了获得最佳性能&#xff0c;我们建议使用全部五根天线。这些天线通常是磁铁安装的鞭状天线&#xff0c;或偶极子天线。我们建议始终使用均匀圆形阵列 (UCA) 天线&#xff0c;因为它可以确定来自各个方…

云计算数据治理

知识星球&#xff1a;数据书局。打算通过知识星球将这些年积累的知识、经验分享出来&#xff0c;让各位在数据治理、数据分析的路上少走弯路&#xff0c;另外星球也方便动态更新最近的资料&#xff0c;提供各位一起讨论数据的小圈子 1.摘要 云计算可以推动创新和各行业应用的…

【Android】如何抓取 Android 设备的 UDP/TCP 数据包?

目录 前言理解抓包tcpdump 实时抓包Wireshark 解包抓包后的一些思考 前言 在真正接触 UDP/TCP 抓包之前&#xff0c;我一直以为这是一项高深莫测的技术。可当我们真正了解之后才发现&#xff0c;其实并没有那么复杂——不过如此。 所谓的大佬&#xff0c;往往只是掌握了你尚未…

Scratch节日 | 六一儿童节射击游戏

六一儿童节快乐&#xff01;这款超有趣的 六一儿童节射击游戏&#xff0c;让你变身小猫弓箭手&#xff0c;守护节日的快乐时光&#xff01; &#x1f3ae; 游戏玩法 上下方向键&#xff1a;控制小猫的位置&#xff0c;自由移动&#xff0c;瞄准目标&#xff01; 空格键&#…