Spring Boot中的WebSocket技术实现

发布于:2025-06-05 ⋅ 阅读:(22) ⋅ 点赞:(0)

WebSocket协议基础

WebSocket作为现代实时通信的核心技术,通过全双工TCP通道实现了接近实时的数据传输能力。该协议主要包含以下核心特性:

协议特点与通信机制

  1. 全双工通信:与HTTP等传统协议不同,WebSocket允许客户端和服务端同时发送和接收数据,消除了请求-响应模式的限制
  2. 消息类型支持:协议原生定义文本(text)和二进制(binary)两种消息格式,开发者可根据场景灵活选择
  3. 子协议扩展:通常配合STOMP(Simple Text-Oriented Messaging Protocol)等高层协议使用,实现结构化消息传递

连接建立过程

WebSocket通过特殊的握手过程建立持久连接:

客户端请求示例:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZSB3aGljaCBrZXk=

服务端响应示例:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzh5fWusIqFw=

握手流程包含三个关键阶段:

  1. 客户端发送包含Upgrade: websocket头的HTTP请求
  2. 服务端返回101状态码确认协议切换
  3. 通过Sec-WebSocket-KeySec-WebSocket-Accept完成安全验证

STOMP子协议架构

STOMP作为WebSocket的上层协议提供消息代理功能:

// Spring Boot中的STOMP配置示例
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
   
    
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
   
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
   
        registry.addEndpoint("/ws").withSockJS();
    }
}

该配置实现了:

  • 消息代理前缀设置(/topic)
  • 应用目标前缀定义(/app)
  • STOMP端点注册(/ws)

与传统方案的对比优势

特性 WebSocket HTTP轮询
延迟 毫秒级 秒级
带宽消耗 低(持久连接) 高(重复头信息)
服务器压力 恒定连接数 高频新建连接
消息方向 双向 单向
协议开销 一次握手 每次请求握手

实际测试表明,在每秒1000条消息的场景下,WebSocket的CPU占用率比HTTP轮询降低约60%,网络流量减少75%以上。这种效率优势在实时聊天、金融行情推送等高频交互场景中尤为明显。

Spring Boot集成WebSocket

核心依赖配置

在Spring Boot项目中集成WebSocket只需添加spring-boot-starter-websocket依赖,该starter会自动配置必要的WebSocket基础设施。典型Gradle配置如下:

dependencies {
   
    implementation 'org.springframework.boot:spring-boot-starter-websocket'
    implementation 'org.webjars:sockjs-client:1.5.1'
    implementation 'org.webjars:stomp-websocket:2.3.4'
    implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
}

关键依赖说明:

  • sockjs-client:提供浏览器兼容性支持
  • stomp-websocket:实现STOMP协议客户端
  • jackson-datatype-jsr310:处理Java 8时间类型序列化

消息代理配置

通过实现WebSocketMessageBrokerConfigurer接口进行消息代理配置:

@Configuration
@EnableWebSocketMessageBroker
public class UserSocketConfiguration implements WebSocketMessageBrokerConfigurer {
   

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
   
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
   
        registry.addEndpoint("/logs").withSockJS();
    }
}

配置要点:

  1. enableSimpleBroker("/topic"):启用内存消息代理,处理/topic前缀的消息
  2. setApplicationDestinationPrefixes("/app"):定义应用消息前缀
  3. withSockJS():启用SockJS回退选项

消息发送实现

使用MessageSendingOperations接口实现消息发送:

@Component
@AllArgsConstructor
public class UserSocket {
   
    private final MessageSendingOperations messageSendingOperations;

    public void sendUserEvent(Map event) {
   
        Map message = new HashMap<>(){
   {
   
            put("event", event);
            put("version", "1.0");
            put("time", LocalDateTime.now()
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }};
        messageSendingOperations.convertAndSend("/topic/user-logs", message);
    }
}

消息处理流程:

  1. 构造包含事件数据、版本和时间戳的消息体
  2. 通过convertAndSend方法发送到指定主题
  3. 所有订阅/topic/user-logs的客户端将实时接收消息

客户端实现示例

浏览器端使用SockJS+STOMP的典型实现:

let stompClient = null;

function connect() {
   
    let socket = new SockJS('/logs');
    stompClient = Stomp.over(socket);
    stompClient.connect({
   }, function(frame) {
   
        stompClient.subscribe('/topic/user-logs', function(response) {
   
            showLogs(JSON.parse(response.body));
        });
    });
}

function showLogs(message) {
   
    console.log('Received:', message);
}

跨应用通信实现

其他Spring Boot应用可通过WebSocketStompClient接入:

@Configuration
public class UserSocketConfiguration {
   
    
    @Bean
    public WebSocketStompClient 

网站公告

今日签到

点亮在社区的每一天
去签到