Socket.IOで動的にnamespaceを追加する

出来る、とはよく見るんですが
あまり実例がなかったので書いてみます。


ちなみにnamespace=チャットルーム、みたいなイメージです。


まず、of*1を利用する場合ですが
基本的にはクライアントがサーバに接続する瞬間には
既にネームスペースが存在している必要があるかな、と思います*2


つまりこういう流れ。

  1. トリガー発生(クライアントから「create_room」みたいなリクエストが来る / DBから取得 / etc...)
  2. サーバ側でネームスペースを追加。
  3. クライアント側では作成されたネームスペースに接続。


今回のAramakiではトリガー(荒巻出現)がサーバ側なので
mongodbを定期的に監視して、
荒巻が出現したら動的にnamespaceを追加する、
という実装にしています。

サーバ側コード(一部のみ)
  // 動的に追加したルームを管理する変数
  var rooms = {};

  // dynamic add room
  // 3秒ごとにスキーマ監視
  setInterval(function() {
    // ルームを保持するスキーマ検索
    matadorschema.find_one(function (err, row) {
      if(err) throw err;

      var room_id = row.id;
      // ルームが作成されていない時
      if (!rooms[room_id] && id ) {
        rooms[id] = 1;

        // ネームスペース追加
        io.of("/room/" + room_id).on("connection", socket_func);

        console.log('create_room! ' + room_id)
      }
    });
  } , 3000);

  // connection
  function socket_func(socket) {
      ...
  }

  ...
クライアント側コード(一部のみ)
  // テンプレート変数とかjavascriptのsearchから設定するとか
  var room_id=???;

  var host = 'localhost:3000';
  // あとは普通にネームスペース接続
  var socket = io.connect('http://'+host+'/room/'+room_id);

  ...


こんな感じでうまくいってます。

*1:Socket.IO v0.7以降

*2:ハックすればできるのかもしれませんが