# OpenClaw Gateway WebSocket 握手超时问题报告

## 问题描述

执行 `openclaw devices list` 或 `openclaw devices clear --yes` 等需要连接 Gateway 的 CLI 命令时，始终无法连接成功，报错：

```
gateway connect failed: Error: gateway closed (1000):
[openclaw] Failed to start CLI: Error: gateway closed (1000 normal closure): no close reason
Gateway target: ws://127.0.0.1:18789
```

Gateway 本身运行正常（`openclaw gateway status` 显示 `RPC probe: ok`），HTTP 连接也正常（curl 返回 200），但 CLI 通过 WebSocket 连接时立即被 Gateway 断开。

## 原因分析

### 直接原因：WebSocket 握手超时

Gateway 日志中记录了明确的超时信息：

```json
{
  "cause": "handshake-timeout",
  "handshake": "failed",
  "durationMs": 6336,
  "handshakeMs": 3000
}
```

CLI 建立 WebSocket 连接后，需要在限定时间内完成握手（发送 `connect` 请求并收到响应）。超过时限未完成握手，Gateway 会主动断开连接，返回 code 1000。

### 根本原因：dist 编译产物中的握手超时配置过短

源码（`src/gateway/server-constants.ts:24`）中定义的默认超时为 **10 秒**：

```typescript
export const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000;
```

但实际安装的 dist 产物（`gateway-cli-CuZs0RlJ.js`）中写死为 **3 秒**：

```javascript
const DEFAULT_HANDSHAKE_TIMEOUT_MS = 15e3; // 原始值为 3e3
```

源码中的 `getHandshakeTimeoutMs()` 函数支持通过 `OPENCLAW_HANDSHAKE_TIMEOUT_MS` 环境变量覆盖超时值，但 dist 中的实现只支持测试专用的 `OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS`（且需 `VITEST` 环境），不支持生产环境变量覆盖。

### 加剧因素：CLI 插件加载耗时

CLI 在连接 Gateway 之前需要加载多个插件：

```
[plugins] feishu_doc: Registered feishu_doc, feishu_app_scopes
[plugins] feishu_chat: Registered feishu_chat tool
[plugins] feishu_wiki: Registered feishu_wiki tool
[plugins] feishu_drive: Registered feishu_drive tool
[plugins] feishu_bitable: Registered bitable tools
[wecom] v1.0.13 loaded
```

这些插件加载耗时约 2-4 秒，加上 CLI 本身的初始化时间，总计超过 3 秒的握手超时限制，导致 Gateway 在 CLI 发起握手之前就已超时断开。

### 版本差异

| 来源 | 握手超时值 | 支持环境变量覆盖 |
|------|-----------|----------------|
| 源码 `src/gateway/server-constants.ts` | 10 秒 | 是 (`OPENCLAW_HANDSHAKE_TIMEOUT_MS`) |
| 已安装 dist `gateway-cli-CuZs0RlJ.js` | 3 秒 | 否（仅测试模式） |

安装版本：`OpenClaw 2026.3.13 (61d171a)`

## 解决方案

### 临时修复：修改 dist 文件中的超时值

直接修改已安装的 dist 文件，将握手超时从 3 秒改为 15 秒：

```bash
sed -i 's/HANDSHAKE_TIMEOUT_MS = 3e3/HANDSHAKE_TIMEOUT_MS = 15e3/' \
  /home/ubuntu/n/lib/node_modules/openclaw/dist/gateway-cli-CuZs0RlJ.js
```

修改后需重启 Gateway：

```bash
systemctl --user restart openclaw-gateway.service
```

### 验证修复

```bash
openclaw devices list
```

正常输出应显示设备列表表格，不再报握手超时错误。

### 注意事项

- 此修复为 dist 文件补丁，执行 `npm update openclaw` 或重新安装后会被覆盖
- 建议关注后续版本是否将源码中的 10 秒超时和环境变量支持同步到正式发布版
- systemd service 文件中添加的 `OPENCLAW_HANDSHAKE_TIMEOUT_MS` 环境变量在当前 dist 版本中不生效，但可作为预留配置

## 相关文件

| 文件路径 | 说明 |
|---------|------|
| `src/gateway/server-constants.ts` | 源码中超时定义 |
| `dist/gateway-cli-CuZs0RlJ.js` | 已安装 dist（已修改） |
| `src/cli/devices-cli.ts` | CLI 设备管理命令 |
| `~/.config/systemd/user/openclaw-gateway.service` | Gateway systemd 服务配置 |
| `~/.openclaw/openclaw.json` | OpenClaw 主配置文件 |
