Skip to content

Allow excluding all sockets in a room #65

Closed
@sebamarynissen

Description

@sebamarynissen

I have a use case where I need to send a message to all sockets except a certain user. In my application I let my sockets join a room equal to their user id, which looks like this:

io.on('connection', () => {
  let user = authenticate(socket);
  socket.join(user.id);
});

I noticed that it was possible to implement this behavior by extending the socket.io adapter as:

const BaseAdapter = require('socket.io-adapter');

class Adapter extends BaseAdapter {
  broadcast(packet, opts) {
    let {
      rooms,
      except = new Set(),
      ...rest
    } = opts;
    if (rooms.size === 0 && except.size > 0) {
      for (let id of [...except]) {
        if (!this.rooms.has(id)) continue;
        for (let sid of this.rooms.get(id)) {
          if (sid !== id) {
            except.add(sid);
          }
        }
      }
    }
    return super.broadcast(packet, {
      rooms,
      except,
      ...rest,
    });
  }
}

which works nicely. (Note that I have implemented some custom logic that allows me to use io.except('user').emit() by calling the namespace's adapter directly.

However, I'm in a position now where I need this functionality to work with socket.io-redis as well. This is a problem because I can't have socket.io-redis extend from my custom adapter. I filed a PR for this but it looks like this is not possible due to TypeScript limitations. Hence I thought it would be a nice functionality to have in the adapter itself. I will file a PR for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions