はじめに
Socket.IOはWebSocketプロトコルの上に構築されたライブラリで、純粋なWebSocketにはない開発者向けの機能を追加します。チャットアプリ、共同編集ツール、ライブダッシュボードなどのリアルタイム機能を構築する場合、クライアントを論理的にグループ化し、通信チャネルを分離し、切断された接続を適切に処理する必要があります。Socket.IOはルーム・名前空間・自動再接続・トランスポートフォールバックを標準で提供するため、これらをゼロから構築する必要はありません。
このレッスンでは、これら4つの機能を具体的なコードで順に学びます。レッスンを終える頃には、サーバーを名前空間に分割し、ソケットを動的にルームにグループ化し、クライアントに自動再接続を許可し、WebSocketがブロックされた場合の安全網としてHTTP long-pollingを利用する方法が理解できます。
名前空間
名前空間は、同じ基盤となるTCP接続を共有する独立した通信チャネルです。デフォルトの名前空間は`/`ですが、カスタム名前空間を作成してロジック上の関心を分離できます。例えば、公開チャットと管理者用コントロールパネルを分ける場合などです。
サーバー側:
クライアント側:
`/admin`名前空間を通じて送信された内容は、同じサーバーとポートで動作していても、デフォルトの`/`名前空間からは完全に分離されます。
ルーム
ルームは名前空間内のサブチャネルです。ソケットはいつでもルームに参加したり退出したりでき、サーバーは1回の呼び出しでルーム内のすべてのソケットにブロードキャストできます。これは、チャットアプリでの会話ごとのメッセージングや、マルチプレイヤーゲームでのゲームルームごとのステート管理に適したパターンです。
`socket.join(roomId)`はソケットをSocket.IOが管理するインメモリのセットに追加します。そして`io.to(roomId).emit(...)`がそのルームの全メンバーにペイロードを配信します。参加したソケット自身は`socket.to(...)`で送信されたメッセージを受信しません。「他の全員」に通知したい場合に`socket.to(...)`を使用してください。
自動再接続とトランスポートフォールバック
純粋なWebSocketは、ネットワークが切断した瞬間に永続的に動作を停止します。Socket.IOのクライアントは再接続を自動的に処理します。再試行戦略を設定し、イベントを通じてユーザーに状況を伝えることができます。
トランスポートフォールバックはレジリエンスのもう半分を担います。Socket.IOは最も低レイテンシなオプションであるため常にWebSocketを最初に試行しますが、ハンドシェイクが失敗した場合(企業ファイアウォール、古いプロキシ、制限のあるネットワーク)は、HTTP long-pollingに透過的にフォールバックします。アプリケーションコードは変わりません。`emit`と`on`の呼び出しはどちらのトランスポート上でも同じように動作します。
よくある落とし穴とまとめ
よく見られる2つの間違いがあります。第一に、ルームメンバーシップを独自の変数に保存しないでください。Socket.IOが内部的にjoinとleaveを管理するため、必ずSocket.IOが返す`socket.rooms`を信頼してください。さもないとキャッシュがずれていきます。第二に、`socket.to(roomId)`は送信者を除外し、`io.to(roomId)`は送信者を含めるため、ブロードキャストの意図に応じて適切な方を選んでください。
まとめると、名前空間はサーバーを分離されたチャネルに分割し、ルームは名前空間内でソケットをグループ化してターゲットを絞ったブロードキャストを可能にし、自動再接続はコードの変更なしにネットワーク切断から復旧し、トランスポートフォールバックはWebSocketがブロックされた場合でも接続を維持します。これら4つの機能が組み合わさることで、純粋なWebSocketの上に書くことになる定型コードを一掃できます。
レッスンのチェックポイント
学んだ内容を復習し、回答へのフィードバックを受けましょう。