WebSocket¶
有两个 WS 端点,面向不同场景。
对比¶
REST /ws(:22222) |
核心 WS(--websocket-port :44444) | |
|---|---|---|
| 协议 | JSON 帧(base64(body)) |
FTAPI binary(44 字节帧头 + protobuf body) |
| 用途 | 推送 only(server → client) | 全双工(兼容 Futu SDK) |
| 客户端 | 浏览器 / websocat / 脚本 |
Futu 官方 futu-api SDK(走 WS transport) |
| 鉴权 | 握手 ?token= 或 Authorization: Bearer |
同 |
| per-message scope | — | v1.0+ 按 proto_id 查 |
REST /ws —— 推送 only¶
适合浏览器前端、轻量脚本。
// 浏览器(WebSocket API 不能设 header,所以用 ?token=)
const ws = new WebSocket('ws://localhost:22222/ws?token=fc_xxxx...')
ws.onmessage = (ev) => {
const event = JSON.parse(ev.data)
// event: { type: 'quote' | 'trade' | 'notify',
// proto_id, sec_key?, sub_type?, acc_id?, body_b64 }
const body = atob(event.body_b64) // protobuf 编码的字节
// ... 解码 body
}
v0.9+:服务端按 client scope 过滤推送:
qot:read-only key → 只收quote+notify,收不到tradeqot:read + acc:read→ 三类都收
核心 WS —— 全双工 binary¶
用 futu-api SDK 的 WebSocket transport,或者 tokio-tungstenite 之类的原生客户端。
握手:HTTP upgrade 时带 ?token= 或 Authorization: Bearer。缺 qot:read scope → HTTP 403 + JSON error。
per-message scope gate(v1.0+):每条消息都会按 proto_id 查 scope,不够就丢弃不响应。客户端会表现为 "请求超时 / 订阅未生效"。
| proto_id | scope |
|---|---|
1xxx 系统 |
无 |
3xxx 行情 + 订阅 |
qot:read |
2005 / 2202 / 2205 / 2237 交易写 |
trade:real |
2xxx 账户读 + 订阅 |
acc:read |
故障排查¶
| 症状 | 原因 |
|---|---|
| 握手 401 | Bearer / ?token 拼错 或 keys.json 里没这把 key |
| 握手 403 | scope 不够 qot:read |
| 订阅成功但收不到推送 | scope 够 qot:read 但不够 acc:read(trade 推送被过滤) |
| 某些命令不响应 | per-message scope 被拒(看 audit log) |
key revoked |
key 被 remove-key + SIGHUP 了 |
审计 + 观测¶
- 握手成功 / 失败都写 audit JSONL(
iface=ws) - 过滤掉的推送计
futu_ws_filtered_pushes_total{required_scope, key_id} - 握手鉴权事件计
futu_auth_events_total{iface="ws"}
详见 审计与可观察性。