技术派整合WebSocket长连接实现消息实时推送
经常使用技术派的小伙伴想必已经注意到,当我们文章被点赞/评论之后,会在右上角收到一个实时的消息弹窗提醒,如下图:

相比较于之前的有消息通知的红色标识,现在的实时通知显然在交互上带来更优的体验效果,那么它是怎么实现的呢? 接下来就让我带大家看一看,如何借助websocket来实现消息的实时通知。
1. 基础知识点
1.1 相关概念释疑
在开始之前,简单介绍一下文中会出现的几个术语:
WebSocket: WebSocket是一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务器之间能够实时地进行双向数据传输,而不需要频繁地建立和关闭连接。这种机制可以提高数据传输的效率和性能。
STOMP: Simple Text Oriented Messaging Protocol 是一种简单而灵活的消息传递协议,它是在HTTP之上实现的。STOMP协议定义了一套简单的命令和帧格式,用于在客户端和服务器之间进行消息传递。通过使用STOMP协议,我们可以实现客户端和服务器之间的双向通讯。
注意:stomp协议属于websocket的子协议
1.2 WebSocket整合STOMP
WebSocket整合STOMP协议实现双向通讯的方案,主要步骤如下:
- 建立WebSocket连接:客户端通过JavaScript的WebSocket API与服务器建立连接。
- 发送STOMP帧:在WebSocket连接建立后,客户端和服务器就可以通过发送STOMP帧来进行通信了。STOMP帧是STOMP协议的基本单位,它定义了消息的各种操作,如订阅、发布等。
- 处理STOMP帧:服务器收到STOMP帧后,会根据帧的类型进行相应的处理。例如,如果收到一个SUBSCRIBE帧,服务器就会为客户端创建一个订阅;如果收到一个SEND帧,服务器就会将消息发送给指定的目的地。
- 关闭WebSocket连接:当客户端和服务器都完成了通信后,可以通过调用WebSocket API的close方法来关闭连接。
1.3 SpringBoot整合STOMP流程
SpringBoot对websocket提供了非常友好的封装,对于业务开发而言,可以简单迅速的搭建一个基于STOMP协议的websocket应用工程

上图展示了STOMP的基本工作流程。
步骤1:初始化
服务端:
- 定义接收建立
WebSocket连接的端点EndPoint。 - 配置消息代理
Broker,用于前端订阅(subscribe),后端向该Broker写入消息后,订阅了该Broker的前端都会收到相应的消息。 - 配置路由转发规则,将用户发送的信息转发给相应的处理器(类似于
RequestMappingHandlerMapping和@RequestMapping注解,在WebSocket中使用的是Destination+@MessageMapping)。
客户端:
- 与EndPoint建立连接。
- 订阅Broker,注册消息回调。
步骤2:通讯
服务端:
- 主动向Broker写入消息:使用
simpMessagingTemplate。 - 消息应答:使用
@SendTo注解。
客户端:
- 发送消息:调用send(xxxx)方法。
- 消息应答:触发订阅的回调函数
2. WebSocket集成
我们首先看一下如何在 Spring Boot 应用中,集成WebSocket实现双向通信
2.1 依赖配置
在pom.xml配置文件中,引入websocket的核心依赖
org.springframework.boot
spring-boot-starter-websocket
2.2 WebSocket 配置
正如前面流程图中介绍的,后端需要先配置一下websocket的相关信息,通过实现配置类WebSocketMessageBrokerConfigurer来定义
@Slf4j
@Configuration
@EnableWebSocketMessageBroker // 开启websocket代理
public class WsChatConfig implements WebSocketMessageBrokerConfigurer {
/**
* 这里定义的是客户端接收服务端消息的相关信息,如派聪明的回答: WsAnswerHelper#response 就是往 "/chat/rsp" 发送消息
* 对应的前端订阅的也是 chat/index.html: stompClient.subscribe(`/user/chat/rsp`, xxx)
*
* @param config
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
// 消息代理指定了客户端订阅地址,前端订阅的就是这个路径, 接收后端发送的消息
// 对应 index.js中的 stompClient.subscribe('/topic/hello'
registry.enableSimpleBroker("/topic");
// 表示配置一个或多个前缀,通过这些前缀过滤出需要被注解方法处理的消息。
// 例如,前缀为 /app 的 destination 可以通过@MessageMapping注解的方法处理,
// 而其他 destination (例如 /topic /queue)将被直接交给 broker 处理
config.setApplicationDestinationPrefixes("/app");
}
/**
* 添加一个服务端点,来接收客户端的连接
* 即客户端创建ws时,指定的地址, chat/index.html: let socket = new WebSocket(`${protocol}//${host}/gpt/${session}/${aiType}`);
* @param registry
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 消息代理指定了客户端订阅地址,前端订阅的就是这个路径, 接收后端发送的消息
// 对应 index.js中的 stompClient.subscribe('/topic/hello'
registry.enableSimpleBroker("/topic");
}
}
- 定义端点:
registerStompEndpoints() - 定义客户端与服务端通讯信息:
configureMessageBroker()
-
- 配置消息代理:
registry.enableSimpleBroker - 配置消息转发:
registry.setApplicationDestinationPrefixes,转发前缀可以是多个
- 配置消息代理:
上面的配置完毕之后,对于客户端而言
- 建立连接的路径是:
/ws/hello - 订阅消息的路径是:
/topic/xxx
- 订阅的路径全程,是由
@SendTo的路径来确定
- 接收前端消息的路径是:
/app/xxx
- 后面的这个xxx,是由
@MessageMapping中的路径来补齐
2.3 消息接收应答
@Controller
public class HelloController {
/**
* 当接受到客户端发送的消息时, 发送的路径是: /app/hello (这个/app前缀是 StompConfiguration 中的配置的)
* 将返回结果推送给所有订阅了 /topic/hello 的消费者
*
* @param content
* @return
*/
@MessageMapping("/hello")
@SendTo("/topic/hello")
public String sayHello(String content) {
return "resp: " + content + " | " + LocalDateTime.now();
}
}
实现一个非常简单的消息应答,接收客户端朝 /app/hello 发送的消息,然后将结果写回到 /topic/hello 对应的Broker,那么订阅了这个broker的客户端,都会收到这个应答消息了
再写一个定时器,由后端定时的向/topic/hello这个Broker中写入消息,模拟后台主动下发消息的场景
/**
* 服务端,像订阅了 /topic/hello 的连接端主动发送消息
*
* @throws IOException
*/
@Scheduled(cron = "0/10 * * * * ?")
public void sc1() throws IOException {
String rspMsg = Thread.currentThread().getName() + " 自动返回 | sc1:" + LocalDateTime.now();
// 后端主动给前端发送消息
simpMessagingTemplate.convertAndSend("/topic/hello", rspMsg);
}
2.4 前端DEMO
Hello WebSocket
未能定位到原文的划线
已加入星球,可直接知识星球授权登录
二哥编程星球目前包含:
企业级Agent工作流编排项目PaiFlow
Vibe Coding版本的PaiAgent
派聪明RAG AI知识库Java版本+Go版本
微服务 PmHub、技术派、MYDB
求职派JobClaw(OpenClaw/Hermes架构
PaiCLI(类似Claude Code的Agent
派简历(代码已完成)
等实战项目。
1. 微信扫右侧的优惠券加入知识星球
2. 解锁星球的实战项目教程和源码:
项目源码+教程获取
真诚点赞 诚不我欺
回复