| この記事の要点 |
|
概要
WebSocket は、1 本の TCP 接続の上で、クライアントとサーバが双方向 (全二重) に、かつリアルタイムにデータをやり取りするためのプロトコルです (RFC 6455)。通常の HTTP は「クライアントが要求し、サーバが応答する」という一方向のやり取りの繰り返しで、サーバ側から自発的にデータを送ることができません。WebSocket はこの制約を取り払い、サーバからクライアントへいつでも push できる「つなぎっぱなしの通信路」を提供します。親セクションは Web通信プロトコル です。
仕組み
WebSocket 接続は、まず通常の HTTP リクエストとして始まります。クライアントは Upgrade: websocket と Connection: Upgrade ヘッダを付けてリクエストし、サーバが 101 Switching Protocols で応答すると、その TCP 接続はそのまま WebSocket 通信路へ切り替わります。これを WebSocket ハンドシェイク と呼びます。
- アップグレード: HTTP から WebSocket へ昇格するため、既存の 80/443 ポートと HTTP インフラ (プロキシ・ロードバランサ) をそのまま活用できます。
- フレーム単位の双方向通信: ハンドシェイク後は HTTP のリクエスト/レスポンスではなく、軽量な「フレーム」を双方向に送り合います。テキストフレームとバイナリフレームがあります。
- ハートビート: 接続が生きているか確認するため ping フレームを送り、相手が pong を返します。無応答なら切れたとみなして再接続します。
URL スキームは 2 種類あり、平文の ws:// と TLS で暗号化された wss:// があります。HTTP に対する HTTPS と同じ関係で、本番環境では盗聴・改ざんを防ぐため wss:// を使うのが基本です。
実用例
ブラウザ標準の WebSocket API を使うと、数行でサーバとリアルタイム通信できます。下記は接続し、メッセージを送受信し、ハートビートを送る最小例です。
// ブラウザ側 (JavaScript)
const ws = new WebSocket("wss://example.com/chat");
ws.onopen = () => {
console.log("接続しました");
ws.send(JSON.stringify({ type: "join", room: "general" }));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
console.log("受信:", msg);
};
ws.onclose = () => console.log("切断されました");
ws.onerror = (e) => console.error("エラー", e);
// ハートビート: 30 秒ごとに ping 代わりのメッセージを送る
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: "ping" }));
}
}, 30000);
サーバ側は Node.js の ws ライブラリ、Python の websockets、Go の gorilla/websocket などで実装します。接続中のクライアント一覧を保持し、誰かの発言を全員に配信 (ブロードキャスト) するのが典型的なチャット実装です。
主な用途
- チャット・メッセージング: 双方向の即時配信で、リロードなしにメッセージが届く。
- リアルタイム通知: サーバ発生イベント (いいね・コメント・アラート) を即座に push する。
- ライブ更新: 株価・スポーツのスコア・ダッシュボードの数値をリアルタイムに反映する。
- 共同編集・オンラインゲーム: 複数ユーザの操作を低遅延で同期する。
HTTP ポーリングとの比較
| 方式 | サーバ→クライアント push | 接続 | 遅延 | オーバーヘッド |
|---|---|---|---|---|
| ポーリング | 不可 (定期的に問い合わせ) | 毎回張り直し | 大きい | 大 (毎回ヘッダ) |
| ロングポーリング | 擬似的に可 | 応答ごとに張り直し | 中 | 中 |
| WebSocket | 可 (全二重) | つなぎっぱなし | 小さい | 小 (軽量フレーム) |
| SSE (Server-Sent Events) | 可 (サーバ→クライアントのみ) | つなぎっぱなし | 小さい | 小 |
注意点
- 本番は wss 必須:
ws://は平文で盗聴・改ざんに弱い。HTTPS ページからは混在コンテンツ扱いでws://がブロックされるためwss://を使う。 - 切断と再接続の設計: モバイルやスリープで接続は容易に切れる。ハートビートで検知し、指数バックオフで自動再接続する仕組みが要る。
- スケールアウトの難しさ: 接続が状態を持つため、複数サーバに分散すると「どのサーバに誰が繋がっているか」の共有が必要 (Redis pub/sub など)。
- プロキシ/LB の対応: 一部の中継機器は長時間のアイドル接続を切る。タイムアウト設定やハートビート間隔の調整が要る。
- 要求-応答で足りるなら不要: 単発の取得なら通常の HTTP/2 で十分。常時接続のコストを払う価値があるかを見極める。
関連リンク
子ページはありません
- HTTP/2
- HTTP/3(QUIC)
- WebSocket
- gRPC
- WebRTC
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Git pushした変更の取消し|revert・履歴変更と保護の注意点 2026-10-15 23:49:01
- Gitでローカルを戻す前に|reset・restoreの違いと退避範囲 2026-10-15 23:49:01
- Git rebaseの使い方|対象範囲・競合解決・pushの判断 2026-10-15 22:50:59
- Git pullの使い方|取込み先・ff-only・競合とstashの注意点 2026-10-15 22:50:59
- Git pushの使い方|送信先・タグ・force-with-leaseの条件 2026-10-15 22:12:47
- Git remoteの設定・確認・削除|SSH URLとfetch/pushの違い 2026-10-15 22:12:47
- Gitリモートリポジトリの作成|初回push・既存履歴・mirrorの注意 2026-10-15 15:48:16
- Gitのuser.name・user.email設定|local/global・確認と過去履歴の注意 2026-10-15 15:30:07
- LinuxにGitをインストール|配布元・初期設定・TLSと認証の確認 2026-10-15 15:30:06
- Git導入と初回push|Linuxサーバー・Windows/macOS・SSH設定 2026-10-15 14:51:54
- Db2のCREATE INDEX|索引定義・INCLUDEと実行計画の確認 2026-10-15 14:10:22
- Db2の自動採番|IDENTITY・ID取得とRESTARTの注意点 2026-10-15 14:10:22
- 【DB2】特定スキーマの全テーブルの全カラム情報を取得する方法 2026-10-15 13:53:15
- Db2のシーケンスとIDENTITYの違い|採番とカタログの確認SQL 2026-10-15 13:53:15
- Db2で複数カラムをUPDATEする方法|SET・WHEREと更新前の値 2026-10-15 13:53:15