news 2026/6/15 21:07:20

SpringBoot从0-1集成STOMP协议快速实现消息转发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot从0-1集成STOMP协议快速实现消息转发

✨重磅!盹猫的个人小站正式上线啦~诚邀各位技术大佬前来探秘!✨

这里有:

  • 硬核技术干货:编程技巧、开发经验、踩坑指南,带你解锁技术新姿势!
  • 趣味开发日常:代码背后的脑洞故事、工具测评,让技术圈不再枯燥~
  • 独家资源分享:开源项目、学习资料包,助你打怪升级快人一步!

👉点击直达→盹猫猫的个人小站👈
🌟 来逛逛吧,说不定能挖到你正在找的技术宝藏哦~

目录

🎨 前言

❓ 什么是STOMP协议?

🌲 环境准备

Pom依赖

🐎 代码步骤

1.配置类

2.用户认证

3. 消息转发

⭕ 总结


欢迎来到 盹猫(>^ω^<)的博客

本篇文章主要介绍了

[SpringBoot从0-1集成STOMP协议快速实现消息转发]
❤博主广交技术好友,喜欢文章的可以关注一下❤

🎨 前言

在即时的消息通信应用开发时,经常需要用到将消息转发给特定人员或群组的功能。这时如果使用WebSocket进行开发,就需要维护发送者和接收者的对应关系,当用户过多时,维护这个关系表会是很大的成本。这时我们就可以使用基于Websocket的STOMP协议,来进行消息的转发处理。

本篇文章就是记录SpringBoot如何集成STOMP协议转发的,但在此之前先来看看什么是STOMP协议。

❓ 什么是STOMP协议?

WebSocket 是浏览器与服务器之间的一种双向通信协议(属于 TCP 层之上的应用层协议),解决了 HTTP “请求 - 响应” 单向通信的痛点。

STOMP(Simple Text Oriented Messaging Protocol,简单文本定向消息协议)基于WebSocket协议的应用层的消息规范,可以理解为 “给 WebSocket 通信制定的‘普通话,在 WebSocket 底层通道之上,定义了统一的消息格式、交互规则、路由机制。

来看看如何集成吧!

Let‘s GO!

🌲 环境准备

Pom依赖

要使用STOMP协议需要用到spring-boot-starter-websocket依赖,在Pom文件的dependencies中添加以下内容:

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

🐎 代码步骤

示例中我们实现如下功能:

用户可以连接到ws://127.0.0.1:8080/ws/plot并完成用户认证,并可订阅/topic/plot/{ID}路径,当用户发布数据到/send/plot/{ID}路径时,将数据转发到所有的订阅了/topic/plot/{ID}的用户。

1.配置类

首先配置类实现WebSocketMessageBrokerConfigurer接口,并使用@EnableWebSocketMessageBroker进行标记这是一个默认的Websocket消息代理,并实现以下方法:

registerStompEndpoints:在该方法中可以配置作为STOMP的路径,并可配置允许跨域访问。(即用户的WebSocket需要连接这个路径)

configureMessageBroker: 在该方法中可以设置作为订阅的代理路径。(即用户可以在这个路径上订阅)

configureClientInboundChannel:配置消息入站通道,如可以在这里配置拦截器对发起的请求进行认证。(这里是自定义的StompTokenValidateInterceptor类作为拦截器)

具体代码如下:

package com.uav.qd.config; import com.uav.qd.interceptor.StompTokenValidateInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.ChannelRegistration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; /** * @author nodcat * @version 1.0 * @since 2025/12/29 下午4:44 */ @Configuration @EnableWebSocketMessageBroker public class WebSocketPlotConfig implements WebSocketMessageBrokerConfigurer { @Autowired StompTokenValidateInterceptor stompTokenValidateInterceptor; /** * 注册STOMP端点,供前端连接 */ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // 标绘协同端点,允许跨域访问,支持WebSocket握手 registry.addEndpoint("/ws/plot") .setAllowedOriginPatterns("*"); } /** * 配置消息代理,实现消息广播 */ @Override public void configureMessageBroker(MessageBrokerRegistry registry) { // 订阅地址 registry.enableSimpleBroker("/topic/plot"); } @Override public void configureClientInboundChannel(ChannelRegistration registration) { // registration.interceptors(stompTokenValidateInterceptor); } }

2.用户认证

在用户认证时需要让StompTokenValidateInterceptor实现ChannelInterceptor接口,并重写preSend方法,这里的认证就可以自定义了,包括从请求头中获取token(或JWT TOKEN),然后查数据库(如果是JWT TOKEN则直接解析认证),通过后返回message即可完成连接。

代码如下:

package com.uav.qd.interceptor; import com.uav.qd.common.constant.Constant; import com.uav.qd.common.exception.SysException; import com.uav.qd.common.security.SecurityUser; import com.uav.qd.entity.SysUserTokenEntity; import com.uav.qd.service.ProjectService; import com.uav.qd.service.SysShiroService; import com.uav.qd.service.SysUserService; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.simp.stomp.StompCommand; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.messaging.support.ChannelInterceptor; import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.stereotype.Component; import java.util.Objects; /** * @author nodcat * @version 1.0 * @since 2026/1/4 上午11:43 */ @Component public class StompTokenValidateInterceptor implements ChannelInterceptor { @Autowired SysShiroService shiroService; private static final String AUTHORIZATION_HEADER = "token"; @Override public Message<?> preSend(@NotNull Message<?> message, MessageChannel channel) { // 1. 获取 STOMP 头访问器,用于读取 STOMP 协议头 StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); if (accessor == null) { return message; } if (StompCommand.CONNECT.equals(accessor.getCommand())) { // 3. 提取 STOMP 连接头中的 Token String token = accessor.getFirstNativeHeader(AUTHORIZATION_HEADER); if (token == null || token.trim().isEmpty()) { throw new SysException("STOMP认证失败:未携带有效Token"); } //这里是查询数据库获取,可根据实际需要修改逻辑 SysUserTokenEntity userEntity = shiroService.getByToken(token); if (userEntity==null){ throw new SysException("STOMP认证失败:Token不存在或已失效"); } Long userId = userEntity.getUserId(); Objects.requireNonNull(accessor.getSessionAttributes()).put(Constant.USER_KEY,userId); } return message; } }

⚠️ 注意:这里可以将用户id等数据放到accessor中,以方便在后面的收到消息中直接获取这些关键数据。

3. 消息转发

消息转发时只需要使用到两个注解进行消息的转发:

@SendTo("/topic/plot/{projectId}"):将消息转发到订阅了该主题的用户。

@MessageMapping("/send/plot/{projectId}"):接收该路径发布的消息。

package com.uav.qd.controller.dash; import com.uav.qd.common.constant.Constant; import com.uav.qd.common.exception.SysException; import com.uav.qd.common.security.SecurityUser; import com.uav.qd.dto.emplan.EmPlanMessageDTO; import com.uav.qd.dto.emplan.OperationMessageDTO; import com.uav.qd.service.PlotProjectService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.handler.annotation.DestinationVariable; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.stereotype.Controller; import java.util.Map; import java.util.Objects; /** * STOMP方案消息处理器 * @author nodcat * @version 1.0 * @since 2025/12/30 上午10:11 */ @Controller public class DashPlotMessageController { @Autowired PlotProjectService plotProjectService; /** * 向其它用户转发当前项目编辑消息 * @param projectId 项目ID * @param message 消息 * @param accessor 认证消息 * @return 共享操作消息 */ @SendTo("/topic/plot/{projectId}") @MessageMapping("/send/plot/{projectId}") public EmPlanMessageDTO handlePlotMessage( @DestinationVariable String projectId, OperationMessageDTO message, SimpMessageHeaderAccessor accessor ) throws Exception { Long userId = getUserId(accessor); //更新缓存内容 plotProjectService.updateCacheData(projectId,message); return EmPlanMessageDTO.builder() .userId(userId) .projectId(projectId) .operate(message.getOperate()) .data(message.getData()) .build(); } /** * 获取认证消息内的用户ID * @param accessor 认证消息 * @return 用户ID */ public Long getUserId(SimpMessageHeaderAccessor accessor){ Map<String, Object> attributes = accessor.getSessionAttributes(); return (Long) Objects.requireNonNull(attributes).get(Constant.USER_KEY); } }

整个写法与RestController的写法类似,可以根据实际需要对消息进行缓存操作等,这里返回的类会以Json字符串的格式返回。

⭕ 总结

通过使用STOMP协议可以很方便的实现对特定订阅用户进行数据转发,无需在后端维护对应关系表,并且实现起来并不困难,只需要简单的配置就可以使用类似于HTTP接口的方式进行逻辑功能的实现。赶紧去试试吧!

上面就是所有文章内容了,如果内容对你有帮助,麻烦留一个赞👍和收藏⭐支持一下!


如果你对区块链内容感兴趣可以查看我的专栏:小试牛刀-区块链

感谢您的关注和收藏!!!!!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 12:02:43

2025年火遍全球的Manus该怎么用?估值几十亿美元Manus该怎么用?

估值几十亿美元Manus该怎么用? 你有没有发现一个问题&#xff0c;身边为什么从来没有人用Manus&#xff1f;那它是怎么做到估计几十亿美元的&#xff1f;因为它本身的定位就不是天天用的AI。 你可能习惯了每天打开ChatGPT问几个问题&#xff0c;或者用Midjourney生成几张图片…

作者头像 李华
网站建设 2026/6/15 12:00:37

深度测评本科生必用TOP8 AI论文网站:开题报告文献综述全解析

深度测评本科生必用TOP8 AI论文网站&#xff1a;开题报告文献综述全解析 学术写作新工具测评&#xff1a;2026年本科生必用AI论文网站TOP8榜单出炉 在当前学术研究日益数字化的背景下&#xff0c;本科生在撰写论文时面临的挑战也愈发复杂。从开题报告到文献综述&#xff0c;再到…

作者头像 李华
网站建设 2026/6/15 12:01:15

Sambert-Hifigan情感控制参数说明:调节语调/语速/情绪强度

Sambert-Hifigan情感控制参数说明&#xff1a;调节语调/语速/情绪强度 &#x1f4d6; 项目简介 本技术博客聚焦于 ModelScope 平台上的 Sambert-Hifigan 中文多情感语音合成模型&#xff0c;深入解析其核心情感控制参数的使用方法。该模型支持通过调节语调、语速与情绪强度等维…

作者头像 李华
网站建设 2026/6/15 12:52:28

OCR识别标准化:CRNN的接口规范

OCR识别标准化&#xff1a;CRNN的接口规范 &#x1f4d6; 项目简介 在数字化转型加速的今天&#xff0c;OCR&#xff08;光学字符识别&#xff09;技术已成为信息自动化处理的核心环节。从发票扫描到文档归档&#xff0c;从路牌识别到手写笔记转录&#xff0c;OCR 正广泛应用于…

作者头像 李华
网站建设 2026/6/15 12:56:35

Llama Factory可视化:无需代码快速定制你的对话AI

Llama Factory可视化&#xff1a;无需代码快速定制你的对话AI 作为一名非技术背景的创业者&#xff0c;你可能经常遇到这样的困扰&#xff1a;想验证一个AI对话产品的想法&#xff0c;却被复杂的代码和命令行操作劝退。今天我要分享的Llama Factory可视化工具&#xff0c;正是为…

作者头像 李华
网站建设 2026/6/15 13:47:56

快速验证:用LLaMA Factory和预配置镜像一小时测试模型可行性

快速验证&#xff1a;用LLaMA Factory和预配置镜像一小时测试模型可行性 作为一名创业者&#xff0c;当你有一个AI产品的想法时&#xff0c;最迫切的需求往往是快速验证技术可行性。本文将介绍如何利用LLaMA Factory框架和预配置镜像&#xff0c;在一小时内完成大模型的基本功能…

作者头像 李华