websocket-engineer について
websocket-engineerは、WebSocketやイベント駆動型システムを設計・運用するエンジニア向けのスキルです。チャット、ダッシュボード、ゲームを対象に、アーキテクチャ選定、スケーリング、接続復旧、性能、安全性を扱います。
主な機能
- 01WebSocketとSocket.IOの設計
- 02Redis Adapterによる水平スケーリング
- 03SSEとプロトコル選定の指針
- 04接続監視と再接続の実践
- 05性能とセキュリティのチェックリスト
活用シーン
- 01リアルタイムチャットの設計
- 02複数サーバーへのSocket.IO拡張
- 03切断やハートビート障害の調査
- 04ライブ更新向けプッシュ方式の選定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ 404kidwiz/ claude-supercode-skills --skill websocket-engineerインストール後、Claude Code で/websocket-engineerを入力して読み込まれたか確認します。
詳細
WebSocket・リアルタイムエンジニア
目的
WebSocket アーキテクチャ、Socket.IO、イベント駆動システムを専門とするリアルタイム通信の専門知識を提供します。数百万の同時接続に対応できる、低遅延の双方向通信システムを構築します。
使用する場面
- チャットアプリ、ライブダッシュボード、マルチプレイヤーゲームを構築する場合
- WebSocket サーバーを水平スケーリングする場合(Redis Adapter)
- 一方向の更新に「Server-Sent Events」(SSE)を実装する場合
- 接続切断、ハートビートの失敗、CORS の問題をトラブルシューティングする場合
- ステートフルな接続アーキテクチャを設計する場合
- ポーリングからプッシュ技術に移行する場合
例
例 1:リアルタイムチャットアプリケーション
シナリオ: エンタープライズ用途向けの、スケーラブルなチャットプラットフォームを構築します。
実装:
- Socket.IO を使用した WebSocket アーキテクチャを設計
- 水平スケーリングのために Redis Adapter を実装
- ルームベースのメッセージルーティングを作成
- メッセージの永続化と履歴を追加
- プレゼンスシステム(オンライン/オフライン)を実装
結果:
- 100,000 件以上の同時接続に対応
- メッセージ配信の平均時間は 50ms
- 接続安定性は 99.99%
- シームレスな水平スケーリング
例 2:ライブダッシュボードシステム
シナリオ: 1 秒未満の間隔で更新されるリアルタイム分析ダッシュボードです。
実装:
- 低遅延の WebSocket サーバーを実装
- 効率的なメッセージバッチ処理戦略を作成
- 複数サーバーに対応するため Redis pub/sub を追加
- クライアント側の更新集約を実装
- 大きなペイロードのために圧縮を追加
結果:
- ダッシュボードを 100ms 未満で更新
- 10,000 件の同時ダッシュボード閲覧に対応
- ポーリングと比べてサーバー負荷を 80% 削減
- 再接続時のデータ損失はゼロ
例 3:マルチプレイヤーゲームバックエンド
シナリオ: 低遅延のマルチプレイヤーゲームサーバーです。
実装:
- バイナリプロトコルを使用した WebSocket サーバーを実装
- 権威サーバーアーキテクチャを作成
- クライアント側の予測と調整を追加
- ラグ補償アルゴリズムを実装
- サーバー側の物理演算と衝突判定を設定
結果:
- エンドツーエンドの遅延は 30ms
- サーバーあたり 1000 人の同時プレイヤーに対応
- ネットワーク状況が変動してもスムーズなゲームプレイを実現
- サーバー権限によるチート耐性
ベストプラクティス
接続管理
- ハートビート:接続状態を確認する ping/pong を実装します
- 再接続:バックオフを伴う自動再接続を実装します
- 状態のクリーンアップ:切断時に適切なクリーンアップを行います
- 接続数の制限:リソースの枯渇を防ぎます
スケーリング
- 水平スケーリング:複数サーバーで Redis Adapter を使用します
- スティッキーセッション:ロードバランサーを適切に設定します
- メッセージルーティング:ブロードキャスト/ユニキャストを効率的にルーティングします
- レート制限:不正利用や過負荷を防ぎます
パフォーマンス
- メッセージのバッチ処理:適切な場合はメッセージをまとめて送信します
- 圧縮:メッセージを圧縮します(permessage-deflate)
- バイナリプロトコル:パフォーマンスが重要なデータにはバイナリを使用します
- 接続プーリング:クライアント接続を効率的に再利用します
セキュリティ
- 認証:ハンドシェイク時に検証します
- TLS:常に WSS を使用します
- 入力検証:受信するすべてのメッセージを検証します
- レート制限:接続数/メッセージ数を制限します
2. 判断フレームワーク
プロトコルの選択
What is the communication pattern?
│
├─ **Bi-directional (Chat/Game)**
│ ├─ Low Latency needed? → **WebSockets (Raw)**
│ ├─ Fallbacks/Auto-reconnect needed? → **Socket.IO**
│ └─ P2P Video/Audio? → **WebRTC**
│
├─ **One-way (Server → Client)**
│ ├─ Stock Ticker / Notifications? → **Server-Sent Events (SSE)**
│ └─ Large File Download? → **HTTP Stream**
│
└─ **High Frequency (IoT)**
└─ Constrained device? → **MQTT** (over TCP/WS)
スケーリング戦略
| 規模 | アーキテクチャ | バックエンド |
|---|---|---|
| < 10k Users | モノリシック Node.js | 単一インスタンス |
| 10k - 100k | クラスタリング | Node.js Cluster + Redis Adapter |
| 100k - 1M | マイクロサービス | Go/Elixir/Rust + NATS/Kafka |
| Global | エッジ | Cloudflare Workers / PubNub / Pusher |
ロードバランサーの設定
- スティッキーセッション: Socket.IO の場合、(ハンドシェイクフェーズで)必須です。
- タイムアウト: アイドルタイムアウトを延長します(例:60 秒以上)。
- ヘッダー:
Upgrade: websocket、Connection: Upgrade。
危険信号 → security-engineer にエスカレーションしてください:
- 認証情報を含む状態で、任意の Origin(
*)からの接続を許可している - 接続リクエストに対するレート制限がない(DoS のリスク)
- URL のクエリパラメーターで JWT を送信している(プロキシログに記録されます)。代わりに Cookie または初期メッセージを使用してください
3. コアワークフロー
ワークフロー 1:スケーラブルな Socket.IO サーバー(Node.js)
目標: 複数のコア/インスタンスにまたがってスケールできるチャットサーバーです。
手順:
-
依存関係をインストールする
npm install socket.io redis @socket.io/redis-adapter -
実装(
server.js)const { Server } = require("socket.io"); const { createClient } = require("redis"); const { createAdapter } = require("@socket.io/redis-adapter"); const pubClient = createClient({ url: "redis://localhost:6379" }); const subClient = pubClient.duplicate(); Promise.all([pubClient.connect(), subClient.connect()]).then(() => { const io = new Server(3000, { adapter: createAdapter(pubClient, subClient), cors: { origin: "https://myapp.com", methods: ["GET", "POST"] } }); io.on("connection", (socket) => { // User joins a room (e.g., "chat-123") socket.on("join", (room) => { socket.join(room); }); // Send message to room (propagates via Redis to all nodes) socket.on("message", (data) => { io.to(data.room).emit("chat", data.text); }); }); });
ワークフロー 3:本番環境向けのチューニング(Linux)
目標: 1 台のサーバーで 50k の同時接続を処理します。
手順:
-
ファイルディスクリプター
- 上限を引き上げます:
ulimit -n 65535。 /etc/security/limits.confを編集します。
- 上限を引き上げます:
-
エフェメラルポート
- 範囲を広げます:
sysctl -w net.ipv4.ip_local_port_range="1024 65535"。
- 範囲を広げます:
-
メモリの最適化
- 機能が不要な場合は、Socket.IO の代わりに軽量な
wsを使用します。 - CPU 負荷が高い場合は、「Per-Message Deflate」(圧縮)を無効にします。
- 機能が不要な場合は、Socket.IO の代わりに軽量な
5. アンチパターンと注意点
❌ アンチパターン 1:ステートフルなモノリス
どのような状態か:
- Node.js のメモリに
users = []配列を保存している。
なぜ問題なのか:
- サーバーを 2 台にスケールすると、サーバー 1 のユーザー A はサーバー 2 のユーザー B と通信できません。
- メモリリークによってプロセスがクラッシュします。
正しい方法:
- Redis を状態ストア(アダプター)として使用します。
- サーバーはステートレスにし、バックエンド(Redis)はステートフルにします。
❌ アンチパターン 2:「サンダリングハード」
どのような状態か:
- サーバーが再起動し、100,000 台のクライアントが即座に再接続する。
- CPU の急増により、サーバーが再びクラッシュする。
なぜ問題なのか:
- 接続のハンドシェイクにはコストがかかります(TLS + 認証)。
正しい方法:
- ランダムなジッター: クライアントは再接続する前に
random(0, 10s)待機します。 - 指数バックオフ: 1 秒、次に 2 秒、次に 4 秒と待機します……
❌ アンチパターン 3:イベントループのブロック
どのような状態か:
socket.on('message', () => { heavyCalculation(); })
なぜ問題なのか:
- Node.js はシングルスレッドです。1 つの重いタスクが、すべての 10,000 件の接続をブロックします。
正しい方法:
- ワーカースレッドまたはメッセージキュー(RabbitMQ/Bull)に処理をオフロードします。
7. 品質チェックリスト
スケーラビリティ:
- アダプター: Redis/NATS アダプターが複数ノード向けに設定されている。
- ロードバランサー:(ポーリングへのフォールバックを使用する場合)スティッキーセッションが有効になっている。
- OS の制限: ファイルディスクリプターの上限が引き上げられている。
レジリエンス:
- 再接続: 指数バックオフとジッターが実装されている。
- ハートビート: Ping/Pong の間隔が設定されている(ロードバランサーのタイムアウトより短い)。
- フォールバック: Socket.IO のフォールバック(HTTP Long Polling)が有効化され、テストされている。
セキュリティ:
- WSS: TLS が有効になっている(セキュアな WebSocket)。
- 認証: ハンドシェイクで認証情報が適切に検証される。
- レート制限: 接続レート制限が有効になっている。
アンチパターン
接続管理に関するアンチパターン
- ハートビートなし:切断された接続を検出できないため、ping/pong を実装する
- メモリーリーク:閉じた接続をクリーンアップしていないため、適切なクリーンアップを実装する
- 無限再接続:バックオフなしで再接続を繰り返すため、指数バックオフを実装する
- スティッキーセッションが必須:ステートレスな設計になっていないため、状態管理に Redis を使用する
スケーリングに関するアンチパターン
- 単一サーバー:1 つのインスタンスを超えてスケーリングできないため、Redis アダプターを使用する
- ロードバランシングなし:サーバーへ直接接続しているため、適切なロードバランサーを使用する
- ブロードキャストストーム:すべての接続に無差別に送信するため、特定の接続を対象にする
- 接続の飽和:サーバーあたりの接続数が多すぎるため、水平スケーリングする
パフォーマンスに関するアンチパターン
- メッセージの肥大化:大きく構造化されていないメッセージを使うため、効率的なメッセージ形式を使用する
- スロットリングなし:送信レートに制限がないため、レート制限を実装する
- ブロッキング処理:同期処理を行うため、非同期処理を使用する
- 監視なし:状況を把握できないため、接続メトリクスを実装する
セキュリティに関するアンチパターン
- TLS なし:暗号化されていない接続を使用するため、必ず WSS を使用する
- 脆弱な認証:単純なトークン検証を使うため、適切な認証を実装する
- レート制限なし:悪用されるおそれがあるため、接続数とメッセージ数の制限を実装する
- CORS の公開:クロスオリジンアクセスを無制限に許可するため、適切な CORS を設定する
コメント
Markdown 対応