Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send message to all sockets except some when running on multiple nodes #3629

Closed
1 of 2 tasks
sebamarynissen opened this issue Aug 6, 2020 · 2 comments
Closed
1 of 2 tasks
Labels
enhancement New feature or request
Milestone

Comments

@sebamarynissen
Copy link
Contributor

sebamarynissen commented Aug 6, 2020

You want to:

  • report a bug
  • request a feature

Current behaviour

When running on multiple nodes with socket.io-redis there is no way to emit a message to all sockets in a namespace except a specific socket if the socket you want to omit is not on that node.

Currently you can only do

socket.broadcast.to('room').emit('hi', 'all');

which won't work on multiple nodes because the socket is not available to all nodes.

Expected behaviour

It would be nice to have a way to broadcast to all sockets except a specific one a node that does not contain the socket we want to omit. I therefore propose to add a method .except(id) that can be used as

io.to('room').except('id').emit('hi', 'all');

Setup

  • OS: any
  • browser: any
  • socket.io version: any

Implementation

I would be happy to file a PR for this if this functionality would be accepted. The implementation could looke like this:

// In namespace.js
function Namespace(server, name){
  this.name = name;
  this.server = server;
  this.sockets = {};
  this.connected = {};
  this.fns = [];
  this.ids = 0;
  this.rooms = [];
  this.flags = {};
  this.omit = [];
  this.initAdapter();
}

Namespace.prototype.except = function(id){
  this.omit.push(id);
  return this;
};

Namespace.prototype.emit = function(ev){

  // ...

  var rooms = this.rooms.slice(0);
  var flags = Object.assign({}, this.flags);
  var except = this.omit.slice(0);

  // reset flags
  this.rooms = [];
  this.flags = {};
  this.omit = [];

  this.adapter.broadcast(packet, {
    rooms: rooms,
    flags: flags,
    except: except
  });

  return this;
};

As far as I know this works with socket.io-redis out of the box. See also socketio/socket.io-redis-emitter#87 for a similar feature for socket.io-emitter.

@darrachequesne darrachequesne added the enhancement New feature or request label Feb 24, 2021
darrachequesne pushed a commit that referenced this issue Mar 1, 2021
New syntax:

```
io.except("room1").emit(...);
io.to("room1").except("room2").emit(...);

socket.broadcast.except("room1").emit(...);
socket.to("room1").except("room2").emit(...);
```

Related:

- #3629
- #3657
@darrachequesne
Copy link
Member

This was implemented in 7de2e87 and included in socket.io@4.0.0.

Example:

io.except("room1").emit(/* ... */); // to all clients except the ones in "room1"
io.to("room2").except("room3").emit(/* ... */); // to all clients in "room2" except the ones in "room3"

socket.broadcast.except("room1").emit(/* ... */); // to all clients except the ones in "room1" and the sender
socket.except("room1").emit(/* ... */); // same as above
socket.to("room4").except("room5").emit(/* ... */); // to all clients in "room4" except the ones in "room5" and the sender

Documentation: https://socket.io/docs/v3/migrating-from-3-x-to-4-0/#Allow-excluding-specific-rooms-when-broadcasting

@darrachequesne darrachequesne added this to the 4.0.0 milestone Mar 11, 2021
@sebamarynissen
Copy link
Contributor Author

Thanks for merging and thanks for the mention in the documentation! 😄

dzad pushed a commit to dzad/socket.io that referenced this issue May 29, 2023
New syntax:

```
io.except("room1").emit(...);
io.to("room1").except("room2").emit(...);

socket.broadcast.except("room1").emit(...);
socket.to("room1").except("room2").emit(...);
```

Related:

- socketio#3629
- socketio#3657
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants