線上狀態(Presence)
OpenClaw 的「線上狀態」是一個輕量級、盡力而為的即時視圖,涵蓋:
- Gateway 本身
- 連線至 Gateway 的用戶端(macOS App、WebChat、CLI 等)
線上狀態主要用於 macOS App Instances 分頁的畫面呈現,以及提供快速的營運可視性。
線上狀態欄位(會顯示什麼)
線上狀態項目是結構化物件,包含以下欄位:
instanceId(非必填但強烈建議提供):穩定的用戶端身分識別(通常為connect.client.instanceId)host:人類可讀的主機名稱ip:盡力取得的 IP 位址version:用戶端版本字串deviceFamily/modelIdentifier:硬體提示mode:ui、webchat、cli、backend、probe、test、node…lastInputSeconds:「距離上次使用者輸入的秒數」(若已知)reason:self、connect、node-connected、periodic…ts:最後更新時間戳(毫秒,自 epoch 起算)
產生端(線上狀態從何而來)
線上狀態項目由多個來源產生,並進行合併。
1) Gateway 自身項目
Gateway 在啟動時會固定填入一筆「self」項目,讓 UI 在任何用戶端連線之前就能顯示 Gateway 主機。
2) WebSocket 連線
每個 WS 用戶端都從 connect 請求開始。握手成功後,Gateway 會為該連線新增或更新一筆線上狀態項目。
為什麼一次性 CLI 指令不會出現
CLI 經常為了短暫的一次性指令而連線。為了避免 Instances 清單被灌滿,client.mode === "cli" 不會轉換為線上狀態項目。
3) system-event 信標
用戶端可透過 system-event 方法定期發送更豐富的信標。macOS App 利用此機制回報主機名稱、IP 和 lastInputSeconds。
4) Node 連線(role: node)
當 Node 透過 Gateway WebSocket 以 role: node 連線時,Gateway 會為該 Node 新增或更新一筆線上狀態項目(流程與其他 WS 用戶端相同)。
合併與去重規則(為什麼 instanceId 很重要)
線上狀態項目儲存在單一的記憶體 Map 中:
- 項目以線上狀態 Key 為索引。
- 最理想的 Key 是穩定的
instanceId(來自connect.client.instanceId),可以在重啟後保持不變。 - Key 不區分大小寫。
如果用戶端在重新連線時沒有提供穩定的 instanceId,可能會出現重複列。
TTL 與容量上限
線上狀態的設計初衷就是暫時性的:
- TTL: 超過 5 分鐘的項目會被清除
- 最大項目數: 200(超出時先移除最舊的)
這確保清單保持即時,並避免記憶體無限增長。
遠端/通道注意事項(Loopback IP)
當用戶端透過 SSH 通道或本地連接埠轉發連線時,Gateway 可能會看到遠端位址為 127.0.0.1。為了避免覆蓋用戶端自行回報的正確 IP,Loopback 遠端位址會被忽略。
消費端
macOS Instances 分頁
macOS App 渲染 system-presence 的輸出,並根據最後更新的時間長短套用狀態指示燈(Active/Idle/Stale)。
除錯技巧
- 要查看原始清單,對 Gateway 呼叫
system-presence。 - 如果看到重複項目:
- 確認用戶端在握手時有送出穩定的
client.instanceId - 確認定期信標使用相同的
instanceId - 檢查連線產生的項目是否缺少
instanceId(此時重複是預期行為)
- 確認用戶端在握手時有送出穩定的