WebSocket
Webブラウザとサーバが接続を保ち、双方向にデータを送り合えるようにするプロトコルである。HTTP/1.1ではGETメソッドによるハンドシェイクで始まり、同じTCPコネクション上でWebSocketの通信へ切り替わる。
イマシルちゃんの解説
チャットで新しい発言が届くたびに画面を更新するのは手間がかかるよね。
WebSocketは、ブラウザとサーバが接続を保ち、どちらからでもデータを送れるようにするプロトコルだよ。
まずブラウザから通信の開始を申し込み、サーバが受け入れたらメッセージをやり取りできるんだ。
そのあとは新しい発言が届いたときに、サーバからブラウザへ知らせを送れるよ。
ブラウザも同じ接続で発言を送れるから、毎回問い合わせ直さなくても会話を続けられるんだ。
こうして双方が必要なときに送れることが、チャットや共同編集を支えているよ。
この解説はわかりやすかったですか?
より深い解説
定義
WebSocketは、RFC 6455で定められた、Webで双方向の通信を行うためのプロトコルである。HTTP/1.1では、最初に接続を切り替える要求(アップグレード)を行う。サーバが受け入れると、同じTCPコネクションの上でWebSocketのフレームを使い、クライアントとサーバのどちらからでもデータを送れるようになる。
ハンドシェイク
(クライアント → サーバ)
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
(サーバ → クライアント)
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
サーバが ステータスコード 101(Switching Protocols)を返すと、以降はWebSocketの通信になる。
HTTPのGETは接続の切替えを申し込むために使う。その後の各メッセージを、毎回HTTPのGETで取得するわけではない。上の手順はHTTP/1.1を使う方式であり、HTTP/2やHTTP/3上のWebSocketには別の確立手順がある。
上で運ぶプロトコルを選ぶ
WebSocketの上で、アプリケーションごとの通信規則を使うことができる。使用する規則を選ぶためのヘッダーがSec-WebSocket-Protocolであり、クライアントが候補を示し、サーバが対応するものを応答で選ぶ。
SIPを運ぶ場合、値としてsipを指定する。WebSocketが確立した後、端末の登録にはSIPのREGISTER、通話開始の要求にはINVITEなどを使う。HTTPでの接続確立と、その後のSIPメッセージ交換は別の段階である。 音声そのものもSIPの登録メッセージで運ぶわけではない。
TLSで保護するwssを使えば、ブラウザとWebSocketサーバ間の通信を暗号化できる。SIPの認証や通話の制御は、SIP側の仕組みとして扱う。
特徴
| 項目 | 内容 |
|---|---|
| URIのスキーム | ws(暗号化なし)、wss(TLSで暗号化) |
| ポート番号 | HTTP、HTTPSと同じ80番、443番を使う。既存のファイアウォールやプロキシを通りやすい |
| 接続を始める側 | クライアント(ブラウザ)。サーバから接続を始めることはできない |
| 接続後の通信 | 双方向。サーバからクライアントへ、いつでもデータを送れる(プッシュ) |
| データの形式 | テキスト(UTF-8)またはバイナリのフレーム。XMLである必要はない |
| オーバーヘッド | 接続後は、HTTPのヘッダーを毎回送らないため小さい |
使われる場面
- チャット、通知
- オンラインゲーム、共同編集
- 株価などのリアルタイムの表示
- IoT機器の監視画面
ほかの方式との比較
| 方式 | 内容 |
|---|---|
| ポーリング | クライアントが、一定間隔でサーバに問い合わせる。更新がなくても通信が発生する |
| ロングポーリング | サーバが、更新があるまで応答を保留する。更新のたびに接続し直す |
| Server-Sent Events | サーバからクライアントへの一方向の送信 |
| WebSocket | 1本の接続で、双方向にいつでも送れる |