WebSocket レッスン1
WebSocketの基本
HTTPとの違い、ハンドシェイク、全二重通信の仕組みを学ぼう
HTTP vs WebSocket
HTTPはリクエスト/レスポンス型のプロトコルです。 クライアントがリクエストを送り、サーバーが応答を返します。サーバーからクライアントへ 自発的にデータを送ることはできません。
一方、WebSocketは一度接続を確立すると、 クライアントとサーバーの両方から自由にデータを送受信できる全二重通信が可能です。
【HTTP通信】
クライアント → リクエスト → サーバー
クライアント ← レスポンス ← サーバー
(毎回接続を張り直す / サーバーから送れない)
【WebSocket通信】
クライアント ←→ 双方向データ ←→ サーバー
(常時接続 / どちらからでも送信可能)
【ポーリング vs WebSocket】
ポーリング: 定期的にHTTPリクエストを送って新しいデータを確認
→ 無駄なリクエストが大量発生、遅延が大きい
WebSocket: 接続を維持し、データが発生したら即座に送信
→ リアルタイム性が高く、オーバーヘッドが小さいハンドシェイクプロセス
WebSocket接続はHTTPアップグレードリクエストから始まります。 最初にHTTPでハンドシェイクを行い、成功するとプロトコルがWebSocketに切り替わります。
// 1. クライアントからのアップグレードリクエスト
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
// 2. サーバーからのアップグレードレスポンス
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
// 3. ここからWebSocketフレームで双方向通信開始
// HTTPヘッダーのオーバーヘッドが不要になる全二重通信(Full-Duplex)
WebSocketの最大の特徴は全二重通信です。 クライアントとサーバーが同時にデータを送受信できます。 これにより、リアルタイム性の高いアプリケーションを構築できます。
半二重通信(HTTP)
一度に一方向のみ通信可能。リクエストを送ったら、レスポンスが返るまで待つ必要がある。
全二重通信(WebSocket)
同時に双方向の通信が可能。サーバーはいつでもクライアントにデータをプッシュできる。
WebSocketのユースケース
WebSocketは以下のようなリアルタイム性が求められるアプリケーションで活躍します。
チャットアプリ
メッセージの即座な送受信。Slack、Discord、LINEなどが代表例。
オンラインゲーム
プレイヤー間のリアルタイム同期。位置情報やアクションの即時反映。
ライブ更新
株価、スポーツスコア、SNSフィードなどのリアルタイム更新。
共同編集
Google Docsのような複数人同時編集。変更の即時反映が必要。
ブラウザのWebSocket API
ブラウザにはネイティブWebSocket APIが組み込まれています。 ライブラリなしでWebSocket通信を実装できます。
// WebSocket接続の作成
const ws = new WebSocket("ws://localhost:3001");
// 接続が開いたとき
ws.addEventListener("open", () => {
console.log("接続成功!");
ws.send("こんにちは、サーバー!");
});
// メッセージを受信したとき
ws.addEventListener("message", (event) => {
console.log("受信:", event.data);
});
// エラーが発生したとき
ws.addEventListener("error", (error) => {
console.error("WebSocketエラー:", error);
});
// 接続が閉じたとき
ws.addEventListener("close", (event) => {
console.log("接続終了:", event.code, event.reason);
});
// メッセージの送信
ws.send(JSON.stringify({ type: "chat", text: "Hello!" }));
// 接続を閉じる
ws.close(1000, "正常終了");Node.jsでWebSocketサーバー
wsパッケージを使ってNode.jsでWebSocketサーバーを作成できます。
// npm install ws
import { WebSocketServer } from "ws";
const wss = new WebSocketServer({ port: 3001 });
wss.on("connection", (ws) => {
console.log("クライアントが接続しました");
// メッセージ受信
ws.on("message", (data) => {
const message = data.toString();
console.log("受信:", message);
// 全クライアントにブロードキャスト
wss.clients.forEach((client) => {
if (client.readyState === 1) { // OPEN状態
client.send(message);
}
});
});
// 接続終了
ws.on("close", () => {
console.log("クライアントが切断しました");
});
// ウェルカムメッセージ
ws.send("サーバーに接続しました!");
});
console.log("WebSocketサーバー起動: ws://localhost:3001");まとめ
- WebSocketはHTTPと異なり、常時接続の全二重通信を実現するプロトコル
- HTTPアップグレードリクエストでハンドシェイクを行い接続を確立する
- チャット、ゲーム、ライブ更新など、リアルタイム性が求められる場面で活躍
- ブラウザにはネイティブWebSocket APIが組み込まれている
- Node.jsではwsパッケージでWebSocketサーバーを簡単に構築できる