You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7.10中如何修改WebSocketGraphQlClient订阅消息类型为start?

解决WebSocketGraphQlClient订阅消息类型不匹配问题

问题背景

使用Spring Boot 2.7.10的WebSocketGraphQlClient执行订阅时,客户端发送的消息类型为subscribe,但服务器期望start类型,导致返回Invalid message type!错误。用Insomnia发送start类型消息可正常工作,日志显示客户端编码的消息类型确实为subscribe。

原因分析

Spring的WebSocketGraphQlClient默认遵循GraphQL over WebSocket Protocol(graphql-ws),该协议中订阅消息类型为subscribe;而你的服务器可能使用的是旧版的Apollo subscriptions-transport-ws协议,该协议中订阅消息类型为start。两者的消息类型枚举不兼容,直接修改通用Jackson序列化器无法生效,因为涉及到WebSocketGraphQlClient.GraphQlWebSocketMessage.Type这个内部枚举类的序列化逻辑。

解决方案

通过自定义Jackson序列化器,将枚举类型SUBSCRIBE映射为字符串start,并在构建WebSocketGraphQlClient时配置该序列化器:

1. 编写自定义枚举序列化器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.graphql.client.WebSocketGraphQlClient;

import java.io.IOException;

public class GraphQlWsTypeSerializer extends JsonSerializer<WebSocketGraphQlClient.GraphQlWebSocketMessage.Type> {
    @Override
    public void serialize(WebSocketGraphQlClient.GraphQlWebSocketMessage.Type type, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 将SUBSCRIBE替换为start,其他类型保持原小写形式
        if (WebSocketGraphQlClient.GraphQlWebSocketMessage.Type.SUBSCRIBE.equals(type)) {
            gen.writeString("start");
        } else {
            gen.writeString(type.name().toLowerCase());
        }
    }
}

2. 构建带自定义编码器的WebSocketGraphQlClient

import org.springframework.graphql.client.WebSocketGraphQlClient;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;

// 初始化WebSocket连接器
ReactorNettyWebSocketClient clientWebSocketConnector = new ReactorNettyWebSocketClient();

// 注册自定义序列化器到Jackson模块
SimpleModule module = new SimpleModule();
module.addSerializer(WebSocketGraphQlClient.GraphQlWebSocketMessage.Type.class, new GraphQlWsTypeSerializer());

// 创建自定义编码器并注册模块
Jackson2JsonEncoder customEncoder = new Jackson2JsonEncoder();
customEncoder.getObjectMapper().registerModule(module);

// 构建配置好的WebSocketGraphQlClient
WebSocketGraphQlClient client = WebSocketGraphQlClient.builder("ws://your-server-endpoint/graphql", clientWebSocketConnector)
        .encoder(customEncoder)
        .build();

3. 使用修改后的客户端执行订阅

client.document("subscription onCommentsAdded { comment}")
        .executeSubscription()
        .subscribe(
                response -> System.out.println("收到订阅消息: " + response.getData()),
                error -> System.err.println("订阅出错: " + error.getMessage())
        );

修改后,客户端发送的订阅消息类型会被替换为start,匹配服务器的要求。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:22:34