使用graphql-ws时WebSocket断网后无法自动重连问题
解决graphql-ws网络断开后不重连、closed回调不触发的问题
问题核心
网络中断(切换WiFi/电脑休眠)时,WebSocket未检测到连接已失效,既不触发closed回调,也不会自动重连,导致订阅全部中断。这是因为原生WebSocket在异常断网场景下,不会立刻收到服务器的关闭帧,连接状态会停留在OPEN,无法触发默认的关闭逻辑。
解决方案:启用心跳机制
给graphql-ws客户端添加心跳配置,定期发送检测帧,主动识别死连接,触发重试逻辑。修改后的代码如下:
createClient({ retryAttempts: 5, shouldRetry: () => true, url: "ws://localhost:8080", // 启用心跳,每30秒发送一次ping帧 keepAlive: 30000, // 禁用懒加载,保持持久连接(可选,根据业务场景调整) lazy: false, on: { connected: () => { console.log("CONNECTED"); }, closed: () => { console.log("CLOSED"); }, error: (e) => { console.log(e); }, // 可选:监听心跳事件,方便排查问题 ping: () => console.log("PING sent"), pong: () => console.log("PONG received"), }, });
关键参数说明
keepAlive: 设置毫秒值,客户端会每隔这个时间发送ping帧给服务器;如果服务器在合理时间内未返回pong,客户端会判定连接已死,触发closed回调并启动重试。lazy: 默认值为true,仅当有活跃订阅时才创建连接;设为false会保持持久连接,更适合实时监听场景,也能更早检测到连接异常。shouldRetry和retryAttempts: 你已配置的重试逻辑之前未触发,是因为客户端没检测到连接断开;启用心跳后,就能正常触发重试流程。
额外排查点
如果配置后仍未生效,可检查:
- 服务器是否支持并正确处理graphql-ws的ping/pong帧
- 浏览器或运行环境是否有WebSocket后台限制(比如电脑休眠时的进程限制)
内容的提问来源于stack exchange,提问作者Nicole Staline
相关产品推荐
相关产品推荐

