189

I am investigating nodejs/socket.io for real time chat, and I need some advice for implementing rooms.

Which is better, using namespace or using the room feature to completely isolate grops of chatters from each other?

what is the real technical difference between rooms and namespace?

Is there any resource usage difference?

T J
  • 42,762
  • 13
  • 83
  • 138
Joseph
  • 3,085
  • 3
  • 23
  • 33

7 Answers7

252

This is what namespaces and rooms have in common (socket.io v0.9.8 - please note that v1.0 involved a complete rewrite, so things might have changed):

  • 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

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

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.

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.

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.

Not sure if that answers your question, but the research leading up to this answer at least helped me see clearer.

Evgeniy Berezovsky
  • 18,571
  • 13
  • 82
  • 156
  • 6
    Is there anything major that has changed on this after socket.io version >= 1.0 ? – Xeroxoid Jan 19 '15 at 17:54
  • 2
    Changes in the last version, read http://socket.io/docs/rooms-and-namespaces/ and this answer can be useful to understand rooms things http://stackoverflow.com/questions/24041220/sending-message-to-a-specific-id-in-socket-io-1-0/24224146#24224146 – Gonzalo Bahamondez Apr 18 '15 at 02:51
  • 1
    Can we say the namespace is a certain area of my web app and room a group of clients in that area? – Onaiggac Aug 19 '15 at 17:44
  • Can you add something about when disconnecting from a room/namespace. What happens to them when the client disconnects or looses the connection temporarily. [Here](http://socket.io/docs/rooms-and-namespaces/#disconnection) is written: *Upon disconnection, sockets leave all the channels they were part of automatically, and no specially teardown is needed on your part.* Is a **Channel** the same as your **Compartment**? – Wilt Oct 09 '15 at 14:42
82

It's an old question but after doing some research on the topic I find that the accepted answer is not clear on an important point. According to Guillermo Rauch himself (see link): although it is theoretically possible to create namespaces dynamically on a running app you use them mainly as predefined separate sections of you application. If, on the other hand you need to create ad hoc compartments, on the fly, to accommodate groups of users/connections, it is best to use rooms.

Julio Garcia
  • 1,904
  • 16
  • 26
22

It depends what you wanna do.

The main difference is that rooms are harder to implement. You must make a method for join the rooms with each page reload.

With namespaces you just need to write var example = io.connect('http://localhost/example'); in your javascript client and client are automatically added in the namespaces.

Example of utilization:

  • rooms: private chat.
  • namespaces: the chat of the page.
6

Rooms and namespaces segment communication and group individual sockets.

A broadcast to a room or to a namespace will not reach everyone just the members.

The difference between namespaces and rooms is the following:

  • Namespaces: are managed in the frontend meaning the user, or an attacker, joins through the frontend and the joining and disconnecting is managed here.
  • Rooms: are managed in the backend, meaning the server assigns joining and leaving rooms.

The difference is mainly who manages them

To decide what to use you must decide if the segmentation should be managed in the frontend or in the backend

zardilior
  • 2,810
  • 25
  • 30
  • 1
    You can still protect namespaces with authorization to prevent attacks. – daniel rubambura Jul 20 '21 at 15:33
  • Indeed @danielrubambura a user without permissions wouldn't be able to set it on the frontend, though it could be created by an authenticated attacker. Let's say I create a namespace which for some reason shows as a chatroom, a public one, it could be named @#$!@#$! and then we would increase a lot the complexity having to sanitize and check for this kind of names. That's just one thing I can think of. Though the scenario I mention could happen I do get that iit is not instrinsic of using namespaces – zardilior Jul 21 '21 at 03:20
  • 1
    There is also a man-in-the-middle attack available if passing an auth token via query string. Just a heads up, you need to make two round trips with the token to avoid this. – camwhite Oct 13 '21 at 18:54
4

Namespaces allow you to create objects with the same name, but they would be separate as they will live in different namespaces, otherwise known as scopes.

This is the same thought process you should have with Socket.IO namespaces. If you are building a modular Node web application, you will want to namespace out the different modules. If you look back at our namespace code, you will see that we were able to listen for the same exact events in different namespaces. In Socket.IO, the connection event on the default connection and connection event on a /xxx namespace are different. For example, if you had a chat and comment system on your site and wanted both to be real time, you could namespace each. This allows you to build an entire Socket.IO application that lives only in its own context.

This would also be true if you were building something to be packaged and installed. You cannot know if someone is already using certain events in the default namespace, so you should create your own and listen there. This allows you to not step on the toes of any developer who uses your package.

Namespaces allow us to carve up connections into different contexts. We can compare this to rooms, which allow us to group connections together.We can then have the same connection join other rooms, as well.

Namespaces allow you to create different contexts for Socket.IO to work in. Rooms allow you to group client connections inside of those contexts.

jinglebird
  • 558
  • 1
  • 5
  • 15
4

There can be rooms within namespaces, which helps to organize the code but there cannot be namespaces inside of rooms. So namespace is a top level segmentation and rooms is a lower level one.

DragonFire
  • 3,722
  • 2
  • 38
  • 51
0

TL/DR

Both namespaces and rooms in Socket.io are very similar, the biggest differences are:

  • Namespaces have rooms inside of them
  • Namespaces are created on the server, and joined from the client
  • Whereas rooms are purely server-sided and the client doesn't know about them

Which one you choose to use is purely based on what you're trying to build.

Here's some more detail, from this helpful post.

Namespaces

Socket.IO allows you to Namespace your sockets, which essentially means assigning different endpoints or paths.

This is a useful feature to minimize the number of resources (TCP connections) and at the same time introduce separation between communication channels.

Namespaces are created on the server side. But they are joined by clients by sending a request to the server. (EX: io.connect('/namespace'))

Rooms

Rooms are subchannels of the namespaces. Rooms are purely a server-side construct and the client knows nothing about them.

You can’t join a room with socket io from the client side, it should happen in the server side. To tackle this you need to emit a socket with the room you want to join as data, and in the server you listen to this socket and call socket.join() with the name or the id of the room that has been sent.
Coder Gautam YT
  • 1,044
  • 7
  • 20