Skip to content

fix(drive): detect half-open realtime sockets with keepalive pings#81

Merged
yurenju merged 1 commit into
mainfrom
claude/drive-realtime-keepalive
Jul 14, 2026
Merged

fix(drive): detect half-open realtime sockets with keepalive pings#81
yurenju merged 1 commit into
mainfrom
claude/drive-realtime-keepalive

Conversation

@yurenju

@yurenju yurenju commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

問題

wspc drive watch 的 realtime WebSocket 被 NAT / edge 默默斷掉(沒有 FIN)時,client 的 WebSocket 永遠不會觸發 close,就一直掛在死 socket 上等事件。結果:從 MCP 更新檔案後本地不同步,直到使用者手動 pause/resume 才補下來。實測案例 socket 早在 30 分鐘前就死了,該時段 debug.log 完全沒有 realtime_event

修正

  • Keepalive ping:連上後每 30s 送 {"type":"ping"},10s 內沒有任何流量就主動關閉 socket,走既有 reconnect(帶 cursor)→ server replay → sync,斷線期間的變更不會遺失。逾時錯誤標記為 realtime error (PING_TIMEOUT),log 可辨識。
  • connector 介面加 send();native connector forward 到 WebSocket.send
  • 解析並靜默處理 server 的 pong;任何 incoming 流量都算 liveness。
  • watch --debug 現在把 realtime connect / reconnect / auth failed / warning 生命週期寫進 .wspc-drive/debug.log(這次調查缺的就是這段)。

睡眠行為

client ping 是 Node setTimeout,不會喚醒睡眠中的電腦;睡眠時 timer 暫停,喚醒後才觸發 → 送 ping → socket 已死 → 10s 後重連補齊。server 端 DO 的 pong auto-response 也不喚醒 hibernated DO。

相關

需搭配 wspc/wspc#847(server 連線時 replay cursor 之後的事件)才完整:本 PR 負責偵測死 socket 並重連,那邊負責重連後補齊 gap。

測試

npm test 521 passed(TDD:新增 3 個 keepalive/pong 測試先跑紅再實作),typecheck 過。

A NAT/edge-dropped WebSocket looks identical to a quiet library: the
watch client waited forever on a dead socket and missed every remote
change (an MCP edit only synced after a manual pause/resume). Ping the
server every 30s and tear the socket down when nothing comes back
within 10s, letting the existing reconnect + server replay path
recover the gap.

- connector gains send(); native connector forwards to WebSocket.send
- pong messages are parsed and handled silently
- any incoming traffic counts as liveness
- watch --debug now logs realtime connect/reconnect/auth/warning
  lifecycle to .wspc-drive/debug.log for future diagnosis
@yurenju yurenju merged commit 7ab8e0e into main Jul 14, 2026
2 checks passed
@yurenju yurenju deleted the claude/drive-realtime-keepalive branch July 14, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant