Skip to content

Emit message to all sockets except specifc one #87

Closed
@sebamarynissen

Description

@sebamarynissen

In web processes we have the option of sending a message to all sockets except a specific one by using broadcasting. It would be nice to have this functionality when sending messages from non-web processes as well.

In order to make the emitter interchangeable with namespaces on web processes (see socketio/socket.io#3629), I propose to add a method .except() which can be used as

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

I'd be happy to file a PR for this if the feature would be accepted. An implementation could look like this:

function Emitter(redis, prefix, nsp){
  this.redis = redis;
  this.prefix = prefix;
  this.nsp = nsp;
  this.channel = this.prefix + '#' + nsp + '#';

  this._rooms = [];
  this._flags = {};
  this._except = [];
}

Emitter.prototype.except = function(id){
  this._except.push(id);
  return this;
};

Emitter.prototype.emit = function(){
  // packet
  var args = Array.prototype.slice.call(arguments);
  var packet = { type: parser.EVENT, data: args, nsp: this.nsp };

  var opts = {
    rooms: this._rooms,
    flags: this._flags,
    except: this._except,
  };

  var msg = msgpack.encode([uid, packet, opts]);
  var channel = this.channel;
  if (opts.rooms && opts.rooms.length === 1) {
    channel += opts.rooms[0] + '#';
  }
  debug('publishing message to channel %s', channel);
  this.redis.publish(channel, msg);

  // reset state
  this._rooms = [];
  this._flags = {};
  this._except = {};

  return this;
};

This should work with socket.io-redis out of the box.

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