afnf.net

Socket.IOのnamespaceとroomの使い分け

Socket.IO 2014/11/11 00:11

Socket.IOのnamespaceとroomの使い分けに迷ったのですが、stackoverflowにぴったりの回答がありました。

http://stackoverflow.com/questions/10930286/socket-io-rooms-or-namespacing


This is what namespaces and rooms have in common (socket.io v0.9.8):

  • Both namespaces (io.of('/nsp')) and rooms (socket.join('room')) are created on the server side
  • Multiple namespaces and multiple rooms share the same (WebSocket) connection
  • The server will transmit messages over the wire only to those clients that connected to / joined a nsp / room, i.e. it's not just client-side filtering

namespaceとroomの共通点(Socket.IO ver0.9.8)

  • namespaceもroomも、サーバサイドで作成される
  • namespaceやroomが複数あっても、同一のWebSocketが共有される
  • サーバは、クライアントが属するnamespaceやroomのみにメッセージを送信する。つまり、クライアント側のフィルタではない。

訳注:翻訳時の最新バージョンは1.2.0です。

The differences:

  • namespaces are connected to by the client using io.connect(urlAndNsp) (the client will be added to that namespace only if it already exists on the server)
  • rooms can be joined only on the server side (although creating an API on the server side to enable clients to join is straightforward)
  • namespaces can be authorization protected
  • authorization is not available with rooms, but custom authorization could be added to the aforementioned, easy-to-create API on the server, in case one is bent on using rooms
  • rooms are part of a namespace (defaulting to the 'global' namespace)
  • namespaces are always rooted in the global scope

差異

  • namespaceは、io.connect(urlAndNsp)によってクライアントから接続される(サーバは、namespaceが存在している場合にだけ、そのnamespaceにクライアントを追加する)
  • roomへの参加ができるのはサーバサイドのみ(クライアントのroom参加を可能にするAPIをサーバサイドに作るのは簡単だけど)
  • authorizationはroomでは利用できないが、roomを使う決心をしたとしても、サーバサイドのカスタム認証APIは簡単に追加できる
  • roomはnamespaceの一部分である(グローバルなnamespaceに初期設定されている)
  • namespaceは常にグローバルスコープに属している

訳注:Socket.IO 1.0で、authorizationはmiddlewareという仕組みに置き換えられましたが、roomで利用できないことには変わりないようです。

To not confuse the concept with the name (room or namespace), I'll use compartment to refer to the concept, and the other two names for the implementations of the concept. So if you

  • need per-compartment authorization, namespaces might be the easiest route to take
  • if you want hierarchically layered compartments (2 layers max), use a namespace/room combo
  • if your client-side app consists of different parts that (do not themselves care about compartments but) need to be separated from each other, use namespaces.

構想と、room/namespaceという名前を混同しないために、構想には区画(compartment)という単語を、その実装にはroomとnamespaceという単語を使う。もし・・・

  • 区画毎の認証が必要な場合、namespaceが一番近道
  • (最大2層の)階層構造の区画が必要な場合は、namespace/roomを組み合わせる
  • クライアントサイドアプリが、分離の必要な異なるパーツ(自身で区画の面倒を見ない)から成り立っている場合、namespaceを使う

An example for the latter would be a large client app where different modules, perhaps developed separately (e.g. third-party), each using socket.io independently, are being used in the same app and want to share a single network connection.

後者の一例として、(例えば第3者が)個別に開発し、それぞれが独立してSocket.IOを使用し、同じアプリケーションで単一のネットワーク接続を共有するようなモジュールを使った、大規模なクライアントアプリが挙げられる。

訳注:後者とは、前述3つめのクライアントサイドアプリの件ですね。

Not having actually benchmarked this, it seems to me if you just need simple compartments in your project to separate and group messages, either one is fine.

実際にこれをベンチマークした訳ではないが、あなたのプロジェクトで、メッセージ分割/グルーピングのためのシンプルな区画が必要な場合は、どちらでも良いと思う。


翻訳は以上です。

「そのroom独自のイベントハンドラ」とかはできない(と思う)ので、機能毎に分ける場合はnamespaceを使う必要がありそうです。

  • チャット機能 = namespace A
    • チャットルーム1 = room A1
    • チャットルーム2 = room A2
  • ニュース機能 = namespace B
    • ニュースカテゴリ1 = room B1
    • ニュースカテゴリ2 = room B2
  • ダイレクトメッセージ機能 = namespace C
    • EさんとFさんのDM = room C1
    • MさんとNさんのDM = room C2

namespace=静的、room=動的という見方もできます。

1つのクライアントを複数のroomにjoinさせることができる点も、差異として挙げられますね。上の例で言えば、1つのクライアントで複数のニュースカテゴリをいっぺんに購読できるのは便利そうです。

また、誰が区画管理の責任を持つか、という点も重要そうです。サーバサイドで制御しなければならない場合は、roomの方が良いかもしれません。

Socket.IO 2014/11/11 00:11
comments (0)

blog-java2 engine (build:2019-02-23 17:57 JST)