Spring Boot WebSocket 学习笔记

星期四, 5月 28, 2026 | 2分钟阅读 | 更新于 星期四, 5月 28, 2026

@

WebSocket 是一种全双工通信协议,相比 HTTP 的"请求-响应"模式,服务端可以主动向客户端推送消息。本文记录我在学习 Spring Boot 集成 WebSocket 过程中的笔记。

为什么需要 WebSocket?

HTTP 协议是单向的,客户端请求 → 服务端响应,服务端无法主动推送。这在以下场景中有问题:

  • 即时通讯(聊天室)
  • 实时通知/推送
  • 实时数据大屏
  • 在线协作编辑

在 WebSocket 之前,常见的"伪推送"方案:

方案缺点
短轮询大量无效请求,浪费资源
长轮询连接长时间占用,并发能力差
SSE仅支持服务端→客户端单向推送

WebSocket 的优势:全双工、低延迟、节省带宽、支持文本和二进制。

WebSocket 协议握手过程

客户端                                    服务端
   |                                        |
   |--- HTTP Upgrade 请求 ----------------->|
   |    Upgrade: websocket                  |
   |    Sec-WebSocket-Key: xxx              |
   |                                        |
   |<-- HTTP 101 Switching Protocols ------|
   |                                        |
   |<====== 双向 WebSocket 数据帧 ========>|

握手基于 HTTP,端口复用 80/443。握手后协议切换为 ws://wss://

Spring Boot 集成方式

有三种方式:

方式适用场景推荐度
原生 WebSocket API简单场景
Spring WebSocketHandler需 Spring 集成但不需 STOMP
STOMP over WebSocket企业级应用推荐

推荐 STOMP 的原因:声明式路由(@MessageMapping)、内置心跳、支持点对点和广播、前端有成熟库。

STOMP 协议简介

STOMP 跑在 WebSocket 之上,提供"目标地址"和"订阅"概念:

SUBSCRIBE
destination:/topic/chat    # 订阅频道

SEND
destination:/app/chat      # 发送消息

核心概念:三种目标前缀

前缀含义
/app应用层入口,消息路由到 @MessageMapping
/topic广播频道,所有订阅者都能收到
/user用户私有频道,Spring 自动路由到特定用户

工程落地

Maven 依赖

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

STOMP 配置类

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic", "/queue");  // 消息代理
        registry.setApplicationDestinationPrefixes("/app"); // 应用层前缀
        registry.setUserDestinationPrefix("/user");         // 用户前缀
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOriginPatterns("*")
                .withSockJS();  // SockJS 降级
    }
}

消息处理器

@Controller
public class ChatController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    // 广播消息
    @MessageMapping("/chat")
    @SendTo("/topic/chat")
    public ChatMessage handleChat(ChatMessage message) {
        return message;
    }

    // 点对点消息
    @MessageMapping("/private")
    public void handlePrivate(ChatMessage message, Principal principal) {
        messagingTemplate.convertAndSendToUser(
            message.getTo(), "/queue/private", message
        );
    }
}

高级话题

心跳机制

registry.enableSimpleBroker("/topic", "/queue")
        .setHeartbeatValue(new long[]{10000, 10000});  // 10秒心跳

集群方案

SimpleBroker 是内存级的,不支持集群。生产环境用 RabbitMQ STOMP:

registry.enableStompBrokerRelay("/topic", "/queue")
        .setRelayHost("rabbitmq-host")
        .setRelayPort(61613);

总结

Spring Boot WebSocket 的核心是 STOMP 协议带来的"消息队列"编程模型:

  • /app:应用入口
  • /topic:广播
  • /user:点对点

理解这三个前缀的分工,就掌握了 Spring WebSocket 的核心。

© 2026 My Blog

🌱 Powered by Hugo with theme Dream.