toolfree

WebSocket 測試

從瀏覽器開一條 WebSocket,送出訊框並看伺服器回什麼。直接連到你的伺服器,所以 localhost 也連得上;1006 會解釋而不是只印出來。

在你的瀏覽器中執行

已關閉
狀態
協商出的子協定

收發紀錄

  1. 目前沒有紀錄。

你的瀏覽器直接連到你輸入的位址,不會經過本站——這也是為什麼本機位址也連得上。

關閉代碼

代碼意義
1000Normal closure
1001Going away
1002Protocol error
1003Unsupported data
1005No status received伺服器不會送出
1006Abnormal closure伺服器不會送出
1007Invalid frame payload data
1008Policy violation
1009Message too big
1010Mandatory extension missing
1011Internal server error
1012Service restart
1013Try again later
1014Bad gateway
1015TLS handshake failed伺服器不會送出

連線是你的瀏覽器發起的,不是本站

這條連線由你自己的瀏覽器直接連到你輸入的位址,完全不經過本站。這件事有兩個值得知道的後果:

關閉代碼 1006——大多數人是為了它來的

1006 不是你的伺服器說的話。你的伺服器送不出這個碼,規格明文禁止,10051015 也一樣。 它是瀏覽器在「連線結束了,但沒有收到關閉訊框」時所報的,意思僅止於此:連線死了,而沒有人說原因。

下面這串裡的某一個,而 WebSocket API 不會告訴你是哪一個:

API 是刻意不給原因的。 一個網頁不可以有能力分辨「連線被拒」和「路由不通」,因為這個差別足以 讓網頁掃描訪客的內網。不是瀏覽器知道卻不給你,是瀏覽器刻意不往上傳。

真正的錯誤通常在瀏覽器自己的主控台裡,而那個地方 JavaScript 碰不到。打開開發者工具,看 主控台和網路分頁的 WS 標籤,常常就能看到那次握手實際拿到的 HTTP 狀態。

混合內容:在任何流量之前就失敗

這個頁面是以 HTTPS 提供的,而安全頁面不允許開啟純 ws:// 連線。瀏覽器會在一個位元組送出去之前 就擋下來——然後把它報成一般的連線失敗,看起來跟伺服器掛掉一模一樣。

這個頁面在開啟連線之前就先檢查,並直接把原因說出來。

localhost 是例外:瀏覽器把回送位址視為安全環境,所以從 HTTPS 頁面用 ws:// 測本機開發伺服器 是可以的。其他位址一律要 wss://

握手,以及代理伺服器為什麼會弄壞它

WebSocket 一開始是一個普通的 HTTP GET,帶著 Upgrade: websocketConnection: Upgrade,只有 在伺服器回 101 Switching Protocols 時才算成功。回任何其他狀態碼都到此為止。

幾乎每一個「本機好好的、上線就爛掉」的 WebSocket 問題,都是反向代理把這兩個標頭吃掉了。nginx 需要明確把它們加回去:

location /ws/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}

proxy_http_version 1.1 這行是關鍵——預設是 1.0,而 1.0 根本沒有 upgrade 機制。逾時那行也是: nginx 預設 60 秒就會關掉閒置連線,症狀是「連線一切正常,然後剛好一分鐘後死掉」。

子協定

第二個選填欄位會送出 Sec-WebSocket-Protocol 標頭,按偏好順序提出一份清單。伺服器挑一個回 給你,頁面上會顯示挑中的是哪一個。實務上會遇到的是 graphql-wsmqttjson

提出一個伺服器沒有回應的子協定,連線會直接死掉,而這一點很常讓人卡住。伺服器一個都不認得 時,它會照樣完成握手、但不回這個標頭——而 RFC 6455 接著要求用戶端必須讓這條連線失敗。瀏覽器 就是這麼做的,於是你拿到 1006,跟「伺服器根本沒開」拿到的是同一個碼。

所以填了子協定就秒斷、清空就連得上,那不是伺服器壞了,是那台伺服器不講你指定的那個子協定。

你不能設標頭,而這件事決定了驗證怎麼做

瀏覽器的 WebSocket API 只收一個網址和一份子協定清單,就這樣。沒有辦法送出 Authorization 標頭——這裡不行,任何瀏覽器裡都不行,換哪個函式庫都不行。

所以伺服器端的驗證只能走別的路:

有些函式庫看起來能從瀏覽器送 Authorization 標頭。它們沒有,它們是把它塞進第一個訊框裡。

關閉代碼

上面的表格列出了全部。要記的是這個結構:

瀏覽器只被允許送出 1000 或 3000–4999 之間的代碼。從這個頁面按中斷,送出的是 1000

相關

我的 IP 位址是你的伺服器看到的東西, CSR 產生器處理 wss:// 背後那張憑證, 訊框收回來之後可以用 JSON 格式化讀。