You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Spring Boot开发WebSocket客户端连接官方STOMP WebSocket服务器

搭建Spring Boot WebSocket客户端连接官方STOMP服务器

我明白你的需求——运行Spring官方指南里的WebSocket STOMP服务器,再用另一个Spring Boot应用作为客户端建立连接。下面我会一步步给你展示完整的配置和代码实现,完全适配官方指南的服务器结构。

核心依赖准备

首先在客户端项目的pom.xml(Maven)或build.gradle(Gradle)里引入必要依赖:

  • Maven:
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
  • Gradle:
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-websocket'
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

WebSocket客户端配置类

创建WebSocketClientConfiguration类,配置STOMP客户端的核心组件:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.stomp.StompSessionHandler;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;
import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.Transport;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;

import java.util.List;

@Configuration
public class WebSocketClientConfiguration {

    @Bean
    public WebSocketClient webSocketClient() {
        return new StandardWebSocketClient();
    }

    @Bean
    public WebSocketStompClient stompClient(WebSocketClient webSocketClient) {
        // 因为官方指南的服务器用了SockJS,所以这里用SockJsClient包装
        List<Transport> transports = List.of(new WebSocketTransport(webSocketClient));
        SockJsClient sockJsClient = new SockJsClient(transports);
        
        WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
        // 设置Jackson消息转换器,兼容服务器的JSON消息格式
        stompClient.setMessageConverter(new org.springframework.messaging.converter.MappingJackson2MessageConverter());
        return stompClient;
    }

    @Bean
    public StompSessionHandler stompSessionHandler() {
        return new CustomStompSessionHandler();
    }
}

自定义StompSessionHandler处理连接与消息

这个类负责处理连接成功、消息接收、异常等逻辑,完全对应官方指南的消息结构:

import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;

import java.lang.reflect.Type;

public class CustomStompSessionHandler extends StompSessionHandlerAdapter {

    @Override
    public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
        // 连接成功后订阅服务器的广播目的地
        session.subscribe("/topic/greetings", this);
        System.out.println("✅ WebSocket客户端已连接,成功订阅/topic/greetings");
        
        // 向服务器发送消息,对应官方指南的控制器映射路径
        session.send("/app/hello", new HelloMessage("来自Spring Boot客户端的问候!"));
    }

    @Override
    public Type getPayloadType(StompHeaders headers) {
        // 指定接收消息的类型,和服务器的Greeting类结构一致
        return Greeting.class;
    }

    @Override
    public void handleFrame(StompHeaders headers, Object payload) {
        Greeting greeting = (Greeting) payload;
        System.out.println("📥 收到服务器消息: " + greeting.getContent());
    }

    @Override
    public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) {
        System.err.println("❌ WebSocket客户端异常: " + exception.getMessage());
    }
}

消息实体类(匹配服务器结构)

必须和官方指南里的实体类结构完全一致,否则消息解析会失败:

// 对应服务器接收的HelloMessage
public class HelloMessage {
    private String name;

    public HelloMessage() {}

    public HelloMessage(String name) {
        this.name = name;
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

// 对应服务器发送的Greeting
public class Greeting {
    private String content;

    public Greeting() {}

    public Greeting(String content) {
        this.content = content;
    }

    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
}

启动客户端连接

添加一个CommandLineRunner组件,在应用启动时自动发起连接:

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.WebSocketStompClient;

@Component
public class WebSocketClientInitializer implements CommandLineRunner {

    private final WebSocketStompClient stompClient;
    private final StompSessionHandler stompSessionHandler;

    // 构造注入Spring容器中的组件
    public WebSocketClientInitializer(WebSocketStompClient stompClient, StompSessionHandler stompSessionHandler) {
        this.stompClient = stompClient;
        this.stompSessionHandler = stompSessionHandler;
    }

    @Override
    public void run(String... args) throws Exception {
        // 服务器的WebSocket端点,和官方指南一致
        String serverUrl = "ws://localhost:8080/gs-guide-websocket";
        stompClient.connectAsync(serverUrl, stompSessionHandler);
        System.out.println("🔄 正在尝试连接WebSocket服务器...");
    }
}

关键注意事项

  • 匹配服务器配置:确保客户端的端点、目的地(/topic/greetings/app/hello)和服务器完全一致,否则无法连接或收发消息
  • SockJS适配:如果服务器启用了SockJS,客户端必须用SockJsClient包装,否则直接用StandardWebSocketClient即可
  • 消息兼容性:实体类的字段名、类型必须和服务器端完全匹配,Jackson转换器才能正确解析JSON消息
  • 异常处理:可以在StompSessionHandler中重写handleTransportError方法,处理连接断开等异常情况

内容的提问来源于stack exchange,提问作者Manuelarte

火山引擎 最新活动