如何測試透過代理建立的 WebSocket 連線

一般 HTTP 探測成功,不代表 WebSocket 工作流程可靠。連線可能完成升級,卻因代理關閉閒置通道、重連時出口改變、Worker 未傳送心跳、DNS 在錯誤位置解析,或用戶端繞過代理直連而失敗。
對於已獲授權的聊天、遙測、瀏覽器自動化、即時價格與應用品質驗證,應把 WebSocket 視為完整生命週期測試,而不是只檢查一個狀態碼。有效結果必須證明升級交握、雙向流量、連線存活、受控關閉與可預測恢復。
定義唯一測試身分
傳送流量前,為每次執行分配非敏感測試編號,並記錄:
- 瀏覽器或用戶端版本;
- 代理協定與閘道標籤;
- 要求地區與出口批次標籤;
- DNS 執行方:本機、瀏覽器、閘道或 SOCKS 遠端 DNS;
- 位址家族;
- 連線開始與結束時間;
- 升級狀態、關閉碼、訊息數量與心跳時間;
- 預期內容標記與最終結論。
不要記錄代理密碼、Authorization、Cookie、可重複使用的工作階段令牌,或含個人資料的訊息內容。僅使用自己控制或已獲授權評估的測試端點。
驗證開啟交握
標準 WebSocket 先透過 HTTP 請求要求伺服器切換協定。應確認:
- 請求確實經過設定的代理;
- 目標主機、連接埠與協定符合計畫;
- 伺服器回傳有效升級,而不是快取頁、重新導向迴圈、登入頁或封鎖頁;
- 必要的子協定協商成功;
- 代理沒有移除升級所需欄位;
- 安全 WebSocket 的 TLS 主機名稱驗證仍然正確。
不能因瀏覽器顯示 socket 已開啟就判定通過。使用相同的非敏感測試編號,把用戶端時間與代理閘道側紀錄關聯起來。
證明兩個方向都能傳輸
已開啟的連線仍可能「半失效」。用戶端傳送小型唯一測試訊息,受控伺服器必須回顯或確認;接著由伺服器傳送獨立訊息,用戶端必須完成內容驗證。
記錄傳送時間、接收時間、方向、位元組數與無害訊息雜湊,原始內容不進入長期日誌。先以單一並行執行,避免不同連線的訊息互相混淆。
若用戶端至伺服器正常,而伺服器至用戶端停止,應檢查代理緩衝、中介層逾時、瀏覽器或 Worker 生命週期,以及應用訂閱狀態。在確定故障邊界前不要輪換出口。
測量真實閒置逾時
許多代理、負載平衡器和應用閘道會關閉安靜連線,文件值也可能與實際路徑不同。
使用階梯測試:
- 建立並驗證連線;
- 讓應用保持 15 秒靜默,再傳送探測;
- 依序測試 30、60、120 與 300 秒;
- 記錄第一次探測或確認失敗的間隔;
- 在相同出口批次重複邊界區間。
安全的應用心跳間隔必須短於最低可重現閒置截止值,並為網路抖動與事件迴圈延遲保留餘量。不要為了維持所有通道而設定過度積極的心跳;大規模任務中,不必要心跳會放大頻寬與負載。
區分協定 Ping/Pong 與應用心跳
部分用戶端公開 WebSocket ping/pong frame;瀏覽器 JavaScript 通常依賴應用層訊息。測試紀錄必須標明具體機制。
心跳測試要驗證三件事:
- 心跳確實透過代理離開用戶端;
- pong 或應用確認在截止時間前返回;
- 確認缺失時,連線會被關閉或隔離,而不是以殭屍連線留在池中。
延遲使用單調計時器,牆上時鐘只用於跨系統關聯。系統時間調整不應產生負心跳延遲。
分開測試黏性路由與重連
連線保持開啟時路徑自然固定,但重新連線屬於新的路由事件。若應用依賴地區、帳戶狀態或上游親和 Cookie,必須明確決定重連是重複使用相同代理工作階段,或刻意建立新工作階段。
執行兩種情境:
- 黏性重連:重複使用核准的工作階段標識,驗證邏輯地區與應用狀態一致;
- 全新重連:新建工作階段並標記為新樣本,驗證應用狀態可安全重建。
不要把兩者都稱為「重試」。它們回答不同問題。重連應使用帶隨機抖動的指數退避;明確拒絕或限流不能觸發快速出口輪換。
驗證關閉行為
測試用戶端正常關閉、伺服器正常關閉、策略拒絕、應用重新啟動、網路中斷與代理關閉。記錄關閉碼,以及對端是否收到關閉交握。
正常關閉應釋放瀏覽器、Worker、代理通道與應用訂閱。異常關閉應進入有界恢復流程,重連後不能留下兩個活動訂閱。
核准代理不可用時,用戶端必須故障關閉,不能回退至裝置直連。IPv4 與 IPv6 需分別測試,因為一個位址家族的代理路徑失敗時,另一個位址家族可能仍可直連。
七項發布矩陣
| 情境 | 單一變數 | 必要證據 |
|---|---|---|
| 基線 | 正常連線 | 有效升級與雙向訊息 |
| 閒置邊界 | 逐步增加靜默時間 | 可重現截止值與安全心跳餘量 |
| 心跳缺失 | 抑制確認 | 偵測並清除殭屍連線 |
| 黏性重連 | 相同代理工作階段 | 維持預期地區與應用狀態 |
| 全新重連 | 新代理工作階段 | 新路徑被標記並重建狀態 |
| 代理遺失 | 閘道不可用 | 故障關閉且無直連回退 |
| 雙棧 | 先 IPv4 後 IPv6 | 每個位址家族的路由與 DNS 證據 |
每項重複足夠次數,以區分確定性策略與短暫路由故障。結論只能是通過、失敗或無法判定,缺少證據不能算通過。
常見疑難排解
升級成功,但連線總在固定時間關閉
測量實際閒置截止值並與心跳時序比較,分別檢查代理、負載平衡器、伺服器、瀏覽器 Worker 與 NAT 的閒置策略。
訊息只能單向到達
檢查訂閱狀態、代理緩衝、事件迴圈健康度,以及中介層是否把連線視為閒置。必須使用兩個方向的受控訊息。
重連後到達錯誤地區
檢查代理工作階段是否重複使用、DNS 是否更換解析器,以及新出口批次是否符合要求地區。驗證回應內容,而不是只看 IP 標籤。
不使用代理時正常,透過代理時失敗
比較交握請求、TLS 驗證、代理驗證、目標連接埠策略與升級欄位處理。不要以停用憑證驗證作為捷徑。
發布檢查清單
- 交握與代理側觀察已成功關聯。
- 雙向訊息都通過受控內容驗證。
- 實際閒置逾時經過測量,而非假設。
- 心跳間隔留有餘量,確認缺失會清除殭屍連線。
- 黏性重連與全新重連為獨立測試。
- 重連使用有界退避與隨機抖動。
- 關閉碼與資源清理已記錄。
- IPv4 與 IPv6 的代理遺失都維持故障關閉。
- 日誌不含可重複使用憑證或不必要訊息內容。
- 明確拒絕與限流訊號受到尊重。
合規說明
WebSocket 測試不會創造存取權限。僅測試自己控制或已獲授權評估的端點與帳戶。遵守存取控制、應用條款、速率限制、資料最小化要求、隱私義務和明確拒絕訊號。不得利用重連或輪換出口規避目的端決定。
相關 98IP 指南
來源說明:IETF,《The WebSocket Protocol》,RFC 6455;MDN Web Docs,WebSocket API。外部來源 URL 僅保存在內部營運紀錄中。