visionA/docs/autoflow/04-architecture/adr/adr-002-tunnel-protocol.md
jim800121chen fb7da5d180 chore(autoflow): migrate .autoflow/ 共享層文件至 docs/autoflow/
依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類
共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git),
讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等
per-branch 筆記。

- 02-prd/        21 個檔(PRD、features、market-analysis 等)
- 03-design/     18 個檔(design-spec、wireframes、flows 等)
- 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等)
- 07-delivery/   3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup)

合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv,
但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
2026-05-04 16:55:55 +08:00

5.5 KiB
Raw Permalink Blame History

ADR-002沿用 POC 的 Tunnel 協定WebSocket + yamux

狀態

Accepted — 2026-04-21

背景 (Context)

visionA Cloud 最核心的技術要素是:瀏覽器透過雲端反向代理,操作使用者本地電腦上的 Kneron 裝置

這要求在「雲端 Proxy」與「使用者電腦的 local agent」之間建立一條

  • 由 local agent 主動出站建立(穿越 NAT / 企業防火牆)
  • 雙向多工:同時傳遞 HTTP 控制指令、長輪詢 WebSocket、MJPEG 串流、推論結果串流
  • 低延遲:串流資料需保留 real-time 特性
  • 可重連:網路短暫斷線後自動恢復

POCedge-ai-platform已用 WebSocket + hashicorp/yamux 實作並驗證可行:

  • 外層 gorilla/websocket 負責「由 client 發起、能穿越企業代理」
  • 內層 yamux 把單條 WebSocket 升級為多工 stream每個 HTTP 請求開一條 yamux stream
  • WebSocket binary frame 之上用 wsconn adapter 把 WebSocket 包成 net.Conn

POC 源碼重點:

  • relay/server.go:收 /tunnel/connect、建立 yamux.Server(netConn)、按 token 收在 map[token]*yamux.Session
  • tunnel/client.goDial WebSocket → yamux.Client() → 接收 stream → 轉給本機 127.0.0.1:3721
  • pkg/wsconn/wsconn.gowebsocket.Connnet.Conn adapterbinary frame

決策 (Decision)

雛形沿用 POC 的 tunnel 協定不做重大改變

  • 外層:github.com/gorilla/websocketversion ≥ 1.5.3
  • 多工:github.com/hashicorp/yamuxdefault config
  • Adapter把 POC 的 wsconn 搬到 visionA-backend/internal/wsconn(或 pkg/wsconn,視是否對外暴露)
  • 端點:WS /tunnel/connect?token=xxxremote-proxy 側)
  • 訊息語義:沿用 POC 的「yamux stream 裡傳完整 HTTP request/response」

沿用的好處:代碼已在 POC 驗證過能穿越 NAT、能處理 WebSocket upgradeproxyWebSocket 的 Hijack 邏輯)、能處理 MJPEG streaming。

雛形會升級的部分(與 ADR-003 相關)

  • Token 生成機制SHA256(MAC) → Pairing Token詳見 ADR-003
  • handleTunnel 加上 token 驗證 hook雛形驗 env 寫死 token未來驗 DB
  • Session 管理抽 interface雛形 in-memory未來 Redis詳見 ADR-001

未來可能會重新評估的項目(非雛形範疇)

  • 若 stream 吞吐或 head-of-line blocking 成瓶頸 → 評估 HTTP/3 (QUIC) 或 gRPC bidi stream
  • 若需要端對端加密(繞過雲端看到明文)→ 在 yamux 之上再包一層 TLS / Noise
  • 若需要跨雲的地理就近路由 → 加入 proxy routing 層,由 local agent 選擇 entrypoint

考慮過的替代方案

方案 優點 缺點 排除原因
重頭設計 gRPC bidi stream 現代 RPC有 code-gen、型別安全 要重新定義所有訊息 schemaPOC 已用 HTTP semantics 讓搬遷成本低 雛形期不值得,未來可升級
HTTP/3 (QUIC) 原生多工 未來標準、天生多工、零 HOL blocking Go 生態的 QUIC 客戶端 / 伺服器還在 beta反向代理成熟度低 還太新
單一 WebSocket 無多工(每請求新開 WS 最簡單 每請求一次 WS handshake~50-200ms串流無法疊加 效能差
SSH tunnel / WireGuard 等 VPN 方案 標準 需要使用者端安裝額外軟體、開特定埠、難穿越企業防火牆 使用者體驗差
純 TCP tunnel over TLS 簡單 通常被企業防火牆封鎖WebSocket 因為外觀像 HTTP 能穿透 穿透力差

後果 (Consequences)

正面影響

  • 零移植成本POC relay / tunnel 程式碼可直接搬到 visionA-backend/internal/relayvisionA-backend/internal/tunnel
  • 已驗證 NAT 穿透POC 測試過能穿越公司 NAT、家用路由器 NAT
  • 已驗證 WebSocket-in-WebSocket:瀏覽器 → Proxy → tunnel stream → local agent 的 WebSocket upgrade 流程POC 的 proxyWebSocket 已處理 Hijack 並雙向 pipe這個最難的部分已經能跑
  • 已驗證 MJPEG streamingPOC 的 handleProxyhttp.Flusher 處理串流回應visionA 的 camera stream 可直接用
  • 擴展空間大yamux 天生多工,一個 tunnel 可以同時跑 10+ 個 HTTP 請求不互相阻塞

負面影響(接受的取捨)

  • 訊息格式是 HTTP 明文yamux stream 內跑的是 raw HTTP request/response需靠 TLSWebSocket 外層保密Proxy 節點可以看到明文請求內容
  • yamux 依賴hashicorp/yamux 已久無大版本更新,但 v0.x 穩定
  • 單 WebSocket = 單 tunnel:一個 local agent 一條 WebSocket若要跨地理區域 active-active需應用層路由
  • HOL blocking 風險低但存在yamux 是多工,但底層單一 TCP connection若網路抖動整條都延遲

風險

  • WebSocket 升級失敗率:企業防火牆 / 中間人代理可能阻擋 WebSocket upgrade。雛形先不處理 fallbackSSE / long-pollTODO
  • 單條 WebSocket 頻寬極限:若使用者端上傳 MJPEG 4K 60fps 會打滿一條 TCP。實測後若有問題再引入「多條 WebSocket + 分流」
  • yamux 的 keepalivePOC 用 default config是否足夠穿越企業 idle timeoutTODO 壓測驗證

合規性

  • Architect 確認
  • POC 實測驗證(edge-ai-platform 已部署到 EC2 + 本地測試)
  • 未來壓測TODO

相關文件

  • Design Doc §3資料流
  • TDD §6Tunnel 協定)
  • TDD §7Session 管理)
  • POC 源碼:edge-ai-platform/server/internal/{relay,tunnel}edge-ai-platform/server/pkg/wsconn