5

I was wondering what the purpose of rooms is. See: https://socket.io/docs/rooms-and-namespaces/

You can basically mimic join and leave with just socket.on and socket.off

Take for example:

(no room)

client:

socket.on('chat', (data) => {
    console.log("chat received", data)
    $(this.$refs.chatBox).append(`
        <div>
            ${data}
        </div>
    `)
})

server:

socket.on('chat', function (id, msg) {
    console.log("id:", id, 'message:', msg)
    socket.broadcast.emit('chat', msg);
    // io.emit('chat', msg)
})

This will now listen to the "chat" and I can turn it off using socket.off("chat")


Now I do something similar but with a room:

client:

// to join
socket.emit('waiting room', socket.id)
// to message
socket.emit('waiting room chat', { msg: this.$refs.waiting_input.value })

server:

socket.on('waiting room', function (id) {
    console.log("socket has joined the waiting room", id);
    socket.join("waiting room")
})

socket.on("waiting room chat", function(payload) {
    console.log("waiting room chat:", payload.msg)
    // io.to("waiting room").emit('waiting room', payload.msg)
    socket.broadcast.to("waiting room").emit('waiting room', payload.msg)
})

Now if I send a message to waiting room chat but a socket hasn't joined the room, it won't receive it. But what advantage does the second method have over the first?

7

Rooms are a tool in socket.io servers for keeping track of groups of connected users. You can then iterate the sockets in a room or broadcast to all of them. There's really nothing more to them than that. The server can put a socket into a room or remove one from a room. When a socket disconnects, it is automatically removed from all rooms it is in.

Each socket is also automatically put into a room whose name is constructed from its socket.id. That allows socket.io to send to any socket when you only have its id.

Your scheme for using only messages and then letting each client decide which messages to listen to is a client-driven scheme (client decides which messages to pay attention to) as opposed to a server-driven scheme and it probably doesn't scale as well because it requires you to send all messages to all clients so that all clients have a chance to listen to them all. Rooms, on the other hand, are a server-driven scheme where the server keeps track (in advance) of which sockets are in which group and only sends messages to the clients that should get those messages. The server both controls things and does it more efficiently.

Plus, in some cases, you can't leave it up to the client to decide what it's allowed to listen to. Imagine you have a chat server that sets up private 1-on-1 chat sessions. In that case, you can't have any circumstance where clientA is allowed to listen in on chat messages for some other chat session. To enforce that, the server has to ONLY send chat messages to the pairwise participants. This is a feature that rooms would be very useful for and your scheme would not.

7
  • Ah I see, so by using socket.join() on the server side I can first validate whether the person should or should be listening to the room, whereas socket.on basically allows anyone to join the room – A. L Dec 11 '17 at 12:02
  • @A.Lau - Not quite. socket.io allows anyone to listen to a given message that is sent to them (if you broadcast all messages to all users). Only the server decides who joins a room. So, by using rooms for managing collections and then broadcasting a given message only to the people in a room, you give the server control of who sees that message. – jfriend00 Dec 11 '17 at 14:38
  • So what's preventing a user from sending a message to people in the room who are listening to an event? So if I do socket.emit('waiting room chat', {msg: "message to all"});, even if the user/socket isn't part of the room, people in that room will still receive the message. – A. L Dec 11 '17 at 23:42
  • @A.Lau - The socket.io client has no ability to send a message to a room. Only the server has that ability. So, for a client to cause a message to be sent to a room, it has to send a message to the server that the server is listening for and then the server decides if that client is allowed to send that message to that room and, if so, the server then broadcasts a message to the desired room. The server has all control over rooms. The client has none. – jfriend00 Dec 11 '17 at 23:47
  • ah right. So just make sure I validate messages before anything. – A. L Dec 11 '17 at 23:52
3

Rooms are a logical grouping construct and have many benefits out of the box for developers using websockets:

  1. Rooms make it easier to broadcast to a given set of clients, without referring to individual socket ids of each client.

  2. A client can be or not be in a room, while staying connected. Hence rooms provide logical "subscription" to the event topics/channels being broadcasted by the server.

  3. Some rooms may be even protected or require higher access levels, this can also be simulated by having client send a "join" request with credentials.

  4. In multiplayer games, each game session or game area/zone is logically equivalent of a room.

  5. When you are running a cluster of server instances, rooms (with help of socket.io bridge adapters) can even group clients connected to different server instances.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.