チャットアプリでメッセージが瞬時に届く。
オンラインゲームで他のプレイヤーの動きがリアルタイムに見える。
株価チャートが刻々と更新される。
こんな「リアルタイム」な体験、どうやって実現されているか気になりませんか?
その答えが「WebSocket(ウェブソケット)」です。
従来のWebは「リクエストしたら返事が来る」という一方通行でした。でもWebSocketなら、サーバーとブラウザが「会話」できるんです。まるで電話のように、双方向でリアルタイムに通信できる。
この記事では、WebSocketの基本的な仕組みから、実際の使い方、どんな場面で活躍するのか、そして簡単な実装方法まで、分かりやすく解説していきます。
WebSocketとは?基本を理解しよう

WebSocketの仕組み
WebSocketは、ブラウザとサーバー間で双方向のリアルタイム通信を可能にする技術です。
従来のHTTP通信との違い:
HTTP(従来の方法):
ブラウザ:「データください!」→
←サーバー:「はい、どうぞ」
ブラウザ:「また、ください!」→
←サーバー:「はい、どうぞ」
毎回お願いしないとデータがもらえない(プル型)
WebSocket:
ブラウザ:「接続します!」→
←サーバー:「了解、つながりました」
←サーバー:「新着メッセージです」
ブラウザ:「返信します」→
←サーバー:「他の人も返信しました」
一度つながれば、お互いに自由に話せる(プッシュ型も可能)
なぜWebSocketが必要?
従来の問題点:
- ページを更新しないと新しい情報が見えない
- 定期的にサーバーに問い合わせる必要がある(ポーリング)
- 無駄な通信が多い
- リアルタイム性に欠ける
WebSocketで解決:
- サーバーから即座にデータを送信可能
- 接続を維持するので高速
- 無駄な通信がない
- 真のリアルタイム通信
WebSocketの特徴
メリット:
- ✅ 双方向通信が可能
- ✅ リアルタイム性が高い
- ✅ 通信量が少ない(ヘッダーが小さい)
- ✅ サーバープッシュが可能
- ✅ 接続が持続的
デメリット:
- ❌ 常時接続なのでサーバー負荷が高い
- ❌ プロキシやファイアウォールで制限される場合がある
- ❌ 実装が少し複雑
- ❌ 古いブラウザでは使えない(最近はほぼ問題なし)
WebSocketが使われている身近なサービス
チャットアプリ
Slack、Discord、LINE:
- メッセージが即座に届く
- 「○○さんが入力中…」の表示
- オンライン状態の表示
- 既読通知
オンラインゲーム
ブラウザゲーム、オンライン対戦:
- プレイヤーの位置情報の同期
- リアルタイムバトル
- チャット機能
- マッチング通知
金融・トレーディング
株価、仮想通貨チャート:
- リアルタイム価格更新
- 取引情報の配信
- アラート通知
- オーダーブック更新
コラボレーションツール
Google Docs、Figma、Notion:
- 同時編集
- カーソル位置の共有
- 変更の即座反映
- コメントのリアルタイム表示
ライブ配信
YouTube Live、Twitch:
- コメントのリアルタイム表示
- 視聴者数の更新
- スーパーチャット通知
- 投票機能
WebSocketの接続フロー
接続の流れ
WebSocket接続は、まずHTTPから始まって、プロトコルを「アップグレード」します。
1. ハンドシェイク(握手):
// ブラウザからのリクエスト
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
2. サーバーの応答:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
3. 接続確立:
これ以降、WebSocketプロトコルで通信
URLの形式
WebSocketのURLは特別な形式を使います。
通常のHTTP:
http://example.com/
![]()
Example Domain
WebSocket:
ws://example.com/chat (非暗号化)
wss://example.com/chat (SSL/TLS暗号化)
wss://(暗号化)を使うことを強く推奨します!
ブラウザでWebSocketを使う(JavaScript)
基本的な実装
接続を開く:
// WebSocket接続を作成
const socket = new WebSocket('wss://example.com/socketserver');
// 接続が開いたとき
socket.addEventListener('open', (event) => {
console.log('接続しました!');
socket.send('Hello Server!');
});
// メッセージを受信したとき
socket.addEventListener('message', (event) => {
console.log('メッセージ受信:', event.data);
});
// エラーが発生したとき
socket.addEventListener('error', (event) => {
console.error('エラー発生:', event);
});
// 接続が閉じたとき
socket.addEventListener('close', (event) => {
console.log('接続が閉じました');
});
簡単なチャットアプリの例
HTML:
<!DOCTYPE html>
<html>
<head>
<title>簡単チャット</title>
</head>
<body>
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="メッセージを入力">
<button onclick="sendMessage()">送信</button>
</body>
</html>
JavaScript:
const socket = new WebSocket('wss://your-server.com/chat');
const messagesDiv = document.getElementById('messages');
const messageInput = document.getElementById('messageInput');
// メッセージ受信
socket.onmessage = (event) => {
const message = document.createElement('div');
message.textContent = event.data;
messagesDiv.appendChild(message);
};
// メッセージ送信
function sendMessage() {
const message = messageInput.value;
if (message && socket.readyState === WebSocket.OPEN) {
socket.send(message);
messageInput.value = '';
}
}
// Enterキーでも送信
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
接続状態の管理
readyStateプロパティ:
// 接続状態をチェック
switch(socket.readyState) {
case WebSocket.CONNECTING:
console.log('接続中...');
break;
case WebSocket.OPEN:
console.log('接続済み');
break;
case WebSocket.CLOSING:
console.log('切断中...');
break;
case WebSocket.CLOSED:
console.log('切断済み');
break;
}
再接続の実装
接続が切れたときに自動で再接続する仕組みです。
class ReconnectingWebSocket {
constructor(url) {
this.url = url;
this.reconnectInterval = 1000; // 1秒後に再接続
this.maxReconnectInterval = 30000; // 最大30秒
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
console.log('接続成功');
this.reconnectInterval = 1000; // リセット
};
this.ws.onclose = () => {
console.log('接続が切れました。再接続します...');
setTimeout(() => {
this.reconnectInterval = Math.min(
this.reconnectInterval * 2,
this.maxReconnectInterval
);
this.connect();
}, this.reconnectInterval);
};
this.ws.onerror = (error) => {
console.error('WebSocketエラー:', error);
this.ws.close();
};
}
send(data) {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(data);
}
}
}
// 使い方
const socket = new ReconnectingWebSocket('wss://example.com/socket');
サーバー側の実装例
Node.js + ws ライブラリ
インストール:
npm install ws
サーバー実装:
const WebSocket = require('ws');
// WebSocketサーバーを作成
const wss = new WebSocket.Server({ port: 8080 });
// 接続されたクライアントを管理
const clients = new Set();
wss.on('connection', (ws) => {
console.log('新しいクライアントが接続しました');
clients.add(ws);
// メッセージ受信
ws.on('message', (message) => {
console.log('受信:', message.toString());
// 全クライアントにブロードキャスト
clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
});
// 切断時
ws.on('close', () => {
console.log('クライアントが切断しました');
clients.delete(ws);
});
// ウェルカムメッセージ
ws.send('サーバーに接続しました!');
});
console.log('WebSocketサーバーがポート8080で起動しました');
Socket.IOを使った実装
Socket.IOは、WebSocketをより簡単に使えるようにしたライブラリです。
特徴:
- 自動再接続
- ルーム機能
- イベントベースの通信
- フォールバック機能(WebSocketが使えない環境でも動く)
サーバー側:
const io = require('socket.io')(3000);
io.on('connection', (socket) => {
console.log('ユーザーが接続しました');
// カスタムイベント
socket.on('chat message', (msg) => {
io.emit('chat message', msg); // 全員に送信
});
// ルームに参加
socket.on('join room', (room) => {
socket.join(room);
socket.to(room).emit('user joined', socket.id);
});
socket.on('disconnect', () => {
console.log('ユーザーが切断しました');
});
});
クライアント側:
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
// メッセージ送信
socket.emit('chat message', 'Hello!');
// メッセージ受信
socket.on('chat message', (msg) => {
console.log('メッセージ:', msg);
});
</script>
セキュリティとベストプラクティス
セキュリティ対策
1. 必ずwss://(暗号化)を使用
// ❌ 悪い例
const socket = new WebSocket('ws://example.com');
// ✅ 良い例
const socket = new WebSocket('wss://example.com');
2. 認証の実装
// トークンを使った認証
const token = localStorage.getItem('authToken');
const socket = new WebSocket(`wss://example.com/socket?token=${token}`);
3. Origin検証
サーバー側で接続元を確認:
wss.on('connection', (ws, req) => {
const origin = req.headers.origin;
if (origin !== 'https://trusted-site.com') {
ws.close(1008, 'Origin not allowed');
return;
}
});
4. メッセージの検証
ws.on('message', (data) => {
try {
const message = JSON.parse(data);
// 入力値の検証
if (typeof message.text !== 'string' || message.text.length > 1000) {
return;
}
// 処理を続ける
} catch (e) {
console.error('不正なメッセージ形式');
}
});
パフォーマンス最適化
1. メッセージのバッチ処理
let messageQueue = [];
let sendTimer = null;
function queueMessage(msg) {
messageQueue.push(msg);
if (!sendTimer) {
sendTimer = setTimeout(() => {
socket.send(JSON.stringify(messageQueue));
messageQueue = [];
sendTimer = null;
}, 100); // 100ms待ってまとめて送信
}
}
2. ハートビート(生存確認)
// クライアント側
setInterval(() => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({ type: 'ping' }));
}
}, 30000); // 30秒ごと
3. バイナリデータの活用
// テキストの代わりにArrayBufferを送信
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setInt32(0, 42);
socket.send(buffer);
よくあるトラブルと解決方法
Q1:接続がすぐ切れる
原因と対策:
- プロキシやロードバランサーのタイムアウト → ハートビート実装
- ネットワークの不安定 → 自動再接続実装
- サーバーの設定 → タイムアウト時間を延長
Q2:CORSエラーが出る
解決方法:
// サーバー側でOriginを許可
const wss = new WebSocket.Server({
port: 8080,
verifyClient: (info) => {
const origin = info.origin;
return origin === 'https://allowed-site.com';
}
});
Q3:メッセージが届かない
チェック項目:
- readyStateがOPENか確認
- JSON.stringifyを忘れていないか
- エラーハンドリングを実装
- ネットワークタブで通信を確認
Q4:スケーリングの問題
対策:
- Redis Pub/Subを使った複数サーバー間の連携
- ロードバランサーでのスティッキーセッション
- 水平スケーリングの実装
WebSocketの代替技術
Server-Sent Events(SSE)
特徴:
- サーバー→クライアントの一方向
- HTTPベースで簡単
- 自動再接続機能付き
使い分け:
- 通知やニュースフィードならSSE
- チャットや対戦ゲームならWebSocket
Long Polling
特徴:
- 古い技術だが確実に動く
- ファイアウォールを通りやすい
- 実装が簡単
WebRTC
特徴:
- P2P通信が可能
- 音声・動画に最適
- 低遅延
まとめ:WebSocketでリアルタイムアプリを作ろう!
WebSocketについて、基本から実装まで解説しました。
重要ポイントのおさらい:
- WebSocketは双方向リアルタイム通信を実現
- HTTPからプロトコルをアップグレード
- チャット、ゲーム、金融など幅広く活用
- wss://(暗号化)を必ず使用
実装の基本:
// 最小限の実装
const socket = new WebSocket('wss://example.com');
socket.onmessage = (e) => console.log(e.data);
socket.send('Hello!');
次のステップ:
- まずは簡単なチャットアプリを作ってみる
- Socket.IOで機能を拡張
- セキュリティ対策を実装
- スケーラブルな設計を学ぶ
WebSocketを使えば、今まで不可能だったリアルタイムな体験が作れます。この記事を参考に、ぜひ自分だけのリアルタイムアプリケーションを作ってみてください!
プッシュ通知、ライブ更新、リアルタイムコラボレーション…可能性は無限大です!
コメント