socket.io で動的に名前空間(namespace)を追加する方法
導入
node.js で socket.io を使って、なんかゲーム作れないかな?と最近いろいろ試している。
そこで、例えばこういうケース
- ユーザが「部屋の新規作成」を選ぶと、新しいチャットルーム的なものができる
に対応する場合、動的に名前空間を追加したくなる。
本題
socket.io で動的に名前空間を追加する際の情報って意外と少ないし、
なんか良さげな方法が見つかりにくいのでとりあえず自分が使っている方法を残す。
説明
クライアント側で、接続時に ID を送る
socket.io は「クライアントがサーバに接続した時」というフックを持っている
[サーバ側]
io.configure(function () { io.set('authorization', function (handshake, callback) { // 処理 }); });
上記のようにかける。
また、クライアント側からはハンドシェイク向けのデータを送信することもでき、
[クライアント側]
var con = io.connect('http://localhost:3000?debug=1');
上記のように、クエリストリングに書くことができる。
つまり、ID を debug=1 の部分に埋め込めば、ソケットサーバ側で ID をとれるということになる。
名前空間(namespace)は動的に追加できる
また、socket.io は動的に名前空間を定義でき、それは、authorization のタイミングでも可能。
上記を踏まえて、このように記述できる。
[クライアント側]
/** * 名前空間 /chat/1 を指定し、 * id=1 をソケットサーバに送信 */ var socket = io.connect('http://localhost:3000/chat/1?id=1');
[サーバ側]
io.configure(function () { io.set('authorization', function (handshake, callback) { /** * クライアントからきた id=1 の部分を取得 * /chat/1 名前空間が存在しなければ、io.of('/chat/' + id) で作成する。 */ var id = handshake.query.id; if (!io.namespaces.hasOwnProperty('/chat/' + id)) { var room = io.of('/chat/' + id); room.on('connection', function (socket) { // 処理 }); } callback(null, true); }); });