如何通过Spring GraphQL客户端发送订阅Ping消息?
Spring GraphQL客户端WebSocket订阅保活解决方案
一、官方内置支持(Spring GraphQL 1.2+)
从Spring GraphQL 1.2.0版本开始,已内置graphql-ws协议的Ping消息自动发送能力,直接通过配置即可启用:
- 在构建
GraphQlWebSocketClient时,调用keepAliveInterval(Duration)方法设置Ping消息发送间隔(建议比服务器超时时间短1分钟左右):
GraphQlWebSocketClient client = GraphQlWebSocketClient.builder() .url("ws://your-server/graphql") .keepAliveInterval(Duration.ofMinutes(4)) .build();
该配置会让客户端定期发送符合graphql-ws规范的Ping消息,服务器收到后会回复Pong,以此维持连接不被断开。
如果使用Spring Boot,也可以通过配置文件直接配置:
spring.graphql.websocket.client.keep-alive-interval=240s
二、低版本手动实现方案(1.2以下)
若使用1.2之前的版本,需要自定义扩展客户端来实现Ping消息定时发送:
- 自定义
WebSocketMessageCodec,在连接建立后启动定时任务发送Ping:
public class KeepAliveWebSocketMessageCodec extends DefaultWebSocketMessageCodec { private final Duration keepAliveInterval; private ScheduledFuture<?> keepAliveTask; public KeepAliveWebSocketMessageCodec(Duration keepAliveInterval) { this.keepAliveInterval = keepAliveInterval; } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { super.afterConnectionEstablished(session); // 启动定时Ping任务 this.keepAliveTask = session.getTaskScheduler().scheduleAtFixedRate( () -> sendPing(session), keepAliveInterval ); } private void sendPing(WebSocketSession session) { try { // 构造符合graphql-ws规范的Ping消息 Map<String, Object> pingMessage = Map.of("type", "ping"); session.sendTextMessage(encode(pingMessage)); } catch (Exception e) { // 发送失败时取消定时任务 if (keepAliveTask != null) { keepAliveTask.cancel(true); } } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { super.afterConnectionClosed(session, status); // 连接关闭时清理定时任务 if (keepAliveTask != null) { keepAliveTask.cancel(true); } } }
- 构建客户端时指定自定义Codec:
GraphQlWebSocketClient client = GraphQlWebSocketClient.builder() .url("ws://your-server/graphql") .messageCodec(new KeepAliveWebSocketMessageCodec(Duration.ofMinutes(4))) .build();
三、关键注意事项
- 务必保证
keepAliveInterval的取值小于服务器设置的WebSocket超时时间,避免在Ping消息发送前连接被主动断开。 - 若服务器对Ping消息有额外要求(比如携带特定字段),可调整自定义Codec中Ping消息的构造逻辑,匹配服务器规范。
内容的提问来源于stack exchange,提问作者Toby Shepheard
相关产品推荐
相关产品推荐

