#このページで確認できること
- Upgrade ハンドシェイクのヘッダーと 101 Switching Protocols を確認する
- DevTools の WS タブで、ブラウザが表示するメッセージや制御フレームの送受信を確認する
- プロキシ / TLSインスペクション経由で「101 が返るか」を切り分ける手順
- 観察するヘッダー:
ConnectionUpgradeSec-WebSocket-KeySec-WebSocket-Accept
公開範囲: このサイトはWebSocketサーバーを提供していません。このページでは仕様と確認方法だけを解説します。
#ハンドシェイク
HTTP/1.1を使う場合、クライアントはUpgradeヘッダーを付けて送ります。サーバーが 101 Switching Protocols を返すと、同じ接続上でWebSocketフレームの通信へ移ります。
GET /ws HTTP/1.1
Host: example.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
response
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
- Sec-WebSocket-Key: クライアントがランダムな16バイト値をBase64で送ります。認証情報ではありません。
- Sec-WebSocket-Accept: Keyと固定GUID
258EAFA5-E914-47DA-95CA-C5AB0DC85B11から計算します。開始ハンドシェイクの確認に使い、認証には使いません。 - 101 応答の後は、同じTCPコネクション上を WebSocketフレーム(opcode: text / binary / ping / pong / close)が双方向に流れる。
- RFC 6455の基本仕様では、クライアントからサーバーへ送るフレームをマスクします。
#通信シーケンス
participants: Client, Server Client -> Server: GET /ws HTTP/1.1 + Upgrade: websocket Server --> Client: HTTP/1.1 101 Switching Protocols note: ここからはHTTPではなくWebSocketフレーム Client -> Server: text frame "hello" Server -> Client: text frame "world" (サーバー起点の送信が可能) Server -> Client: ping frame Client --> Server: pong frame Client -> Server: close frame Server --> Client: close frame
participants: Client, Proxy, Server Client -> Proxy: GET /ws + Upgrade headers Proxy -> Server: Upgrade リクエストを転送 Server --> Proxy: 101 Switching Protocols Proxy --> Client: 101 Switching Protocols note: 以降プロキシは双方向ストリームを転送する Client <-> Server: WebSocket frames (via proxy)
プロキシでの確認: Upgradeはhop-by-hopです。HTTPを終端するプロキシは、Upgradeヘッダーと切り替え後の双方向通信を扱う必要があります。WSSをTCPトンネルとして中継する従来型CONNECTプロキシでは、WebSocketフレームを解析せず転送する構成もあります。接続できない場合は、101応答とidle timeoutを確認します。
#確認方法
自分で管理するWebSocketサーバーに接続し、ブラウザのDevToolsでハンドシェイクとメッセージを確認します。
ブラウザでの構文例 — 接続先は置き換えるconst ws = new WebSocket("wss://<your-host>/ws");
ws.onopen = () => ws.send("hello");
ws.onmessage = (event) => console.log("recv:", event.data);
接続先: HTTPSで開いたページから接続する場合は、通常
wss:// を使います。実際のURL、認証、サブプロトコルは接続先の仕様に合わせてください。
#観測ポイント
| Handshake | HTTP/1.1方式では101が返るか、Sec-WebSocket-Acceptが正しいかを確認します。200や400の場合は、接続先や経路のUpgrade対応を調べます。 |
|---|---|
| DevTools | Network → WS フィルタ。ハンドシェイクのヘッダーと、Messages タブで送受信方向やメッセージ、制御フレームなどを確認できる。フラグメントされたデータの表示単位、色、表示名はブラウザとバージョンにより変わり得る。 |
| Proxy | 101 がクライアントまで届くか。長時間接続が idle timeout(60秒等)で切られないか。Connection/Upgrade ヘッダーがプロキシで落とされていないか。 |
| tcpdump / Wireshark | 平文なら websocket フィルタでフレーム解析可能。ハンドシェイクはHTTPとして、以降はWebSocketフレームとしてデコードされる。マスクの有無も見える。 |
| TLS inspection | 動作は製品と設定で異なります。直接接続では成功し、装置経由では失敗する場合、まず101応答の有無を比較します。 |
#関連
HTTP/2 環境では Upgrade の代わりに CONNECT メソッドの拡張(RFC 8441)でWebSocketをストリームに載せる方式があり、HTTP/3向けにもExtended CONNECTを使うブートストラップ(RFC 9220)が定義されています。実際に利用できるかはクライアント、サーバー、中間装置の対応によります。双方向ストリーミングが目的なら gRPC のstreaming RPCも比較対象になります。