WebSocket 连接失败
概述
本指南涵盖 OpenClaw 网关服务器中的 WebSocket 连接失败,基于 src/gateway/server/ws-connection.ts 中的连接处理逻辑。WebSocket 连接对于客户端和代理之间的实时通信至关重要。
症状
立即断开连接
- 客户端连接后几秒内断开
- 连接建立后无数据交换
- 连接最初看似成功但很快失败
握手超时
- 日志消息:
handshake timeout conn=<connection-id> - 连接因特定超时原因关闭
- 客户端从未完成身份验证/配对握手
过早关闭
- 网关日志中出现警告: "closed before connect"
- 握手阶段连接关闭
- 握手完成前收到关闭事件
噪声辅助连接
- Swift Package Manager 辅助连接立即关闭
- 这些被单独过滤和记录(不是真正的错误)
根本原因
1. 握手超时(第 256-265 行)
网关强制执行握手超时以防止僵尸连接:
默认超时: 通过网关设置可配置 触发条件: 客户端未在超时窗口内完成握手 恢复: 连接关闭,客户端必须重新连接
2. Socket 连接错误(第 185-188 行)
连接建立期间的底层 socket 错误:
常见原因: 网络问题、代理问题、TLS 错误 恢复: 立即关闭,服务器端不重试
3. 握手前客户端关闭(第 215-223 行)
客户端在完成身份验证之前断开连接:
检测: 关闭时 conn.ready 标志为 false
日志记录: 包含连接持续时间用于诊断
恢复: 干净断开,无需状态更新
4. Ed25519 配对失败
如果使用 Ed25519 身份验证,无效的签名或密钥会导致握手失败:
常见原因:
- 公钥/私钥对不匹配
- 签名验证失败
- 凭据过期或被撤销
恢复机制
服务器端恢复
- 在线状态更新: 断开连接时,网关更新在线状态并向其余客户端广播快照
- 节点清理: 对于网关节点,连接从路由表中移除
- 无自动重连: 服务器不尝试重新连接;客户端负责重连
客户端恢复
- 检测断开: 监听 WebSocket
close事件 - 检查关闭码: 检查
event.code和event.reason以了解根本原因 - 指数退避: 使用递增延迟实现重连
- 握手优化: 确保连接后快速完成握手
诊断步骤
步骤 1: 检查网关日志
查找特定连接的日志条目:
步骤 2: 分析关闭码
常见 WebSocket 关闭码:
- 1000: 正常关闭(干净断开)
- 1002: 协议错误(消息格式错误)
- 1008: 策略违规(握手超时)
- 1011: 内部错误(服务器端错误)
步骤 3: 测量连接持续时间
检查日志中的 durationMs 字段:
- < 100ms: 可能是网络/防火墙问题
- 100ms - timeout: 握手缓慢,可能需要优化
- = timeout: 触发握手超时