Spring GraphQL Server关闭WebSocket连接:4400无效消息(GraphiQL可用)
以下是针对你场景的具体排查方向:
检查WebSocket子协议兼容性
Spring Boot官方的spring-boot-starter-graphql默认采用graphql-transport-ws协议,而旧的graphql-spring-boot-starter大概率用的是graphql-ws(旧版协议)。GraphiQL会自动适配协议,但你的Apollo Client代码没更新,可能还在使用旧协议发起连接。要确认客户端WebSocket链接配置里的协议是否和服务端匹配,比如Apollo Client的WebSocketLink是否对应新协议的实现,或者在服务端配置兼容旧协议。核对服务端WebSocket配置
检查application.yml/application.properties里的spring.graphql.websocket.path是否和客户端请求路径一致(默认是/graphql)。另外,WebFlux环境下要排查有没有自定义的WebFilter拦截了WebSocket握手请求,导致握手失败返回4400。验证订阅映射的返回类型与字段匹配
确认@SubscriptionMapping注解的方法返回的是Flux这类Publisher响应式类型,别错误返回普通对象或null。同时检查订阅字段名、参数是否和Schema定义完全一致——GraphiQL能正常运行可能是因为参数/字段完全匹配,但客户端可能存在大小写、参数格式的细微差异。排查客户端握手参数与请求头
抓包对比客户端和GraphiQL的WebSocket请求:- 看
Sec-WebSocket-Protocol请求头是否包含服务端支持的协议(比如graphql-transport-ws) - 检查客户端初始发送的消息格式,新协议要求先发送
{"type":"connection_init"},旧协议则是{"type":"start"} - 如果服务端有鉴权,确认客户端握手阶段是否携带了正确的授权信息,缺失的话可能导致4400断开
- 看
开启服务端详细日志
在application.yml里添加日志配置:logging: level: org.springframework.graphql: DEBUG org.springframework.web.reactive.socket: DEBUG查看握手阶段的具体错误日志,4400错误通常会在日志里给出明确原因,比如子协议不匹配、Schema验证失败、请求格式错误等。
内容的提问来源于stack exchange,提问作者k-wasilewski

