Skip to content

Instantly share code, notes, and snippets.

@mikermcneil
Last active July 17, 2016 02:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikermcneil/971b4e92d833211a0243 to your computer and use it in GitHub Desktop.
Save mikermcneil/971b4e92d833211a0243 to your computer and use it in GitHub Desktop.
Examples of unsubscribing a socket from a room in your Sails app using sails.sockets.leave().

How to use sails.sockets.leave()

Unsubscribe the requesting socket

In a controller action, unsubscribe the requesting socket from the specified room:

leaveFunRoom: function(req, res) {
  if ( _.isUndefined(req.param('roomName')) ) {
    return res.badRequest('`roomName` is required.');
  }

  if (!req.isSocket) {
    return res.badRequest('This endpoints only supports socket requests.');
  }

  var roomName = req.param('roomName');
  sails.sockets.leave(req, roomName, function(err) {
    if (err) {return res.serverError(err);}
    return res.json({
      message: 'Left a fun room called '+roomName+'!'
    });
  });
}

Unsubscribe other sockets by id

You can also unsubscribe other sockets by id. For example, in a service:

/**
 * @required {Number} userId  [the user to ban]
 */
banUser: function(options, cb) {
  options = options || {};
  
  if ( _.isUndefined(options.userId) ) {
    return cb(new Error('`userId` is required.'));
  }

  User.findOne({id: options.userId}).exec(function (err, user) {
    if (err) { return cb(err); }
    if (!user) { return cb(new Error('Failed to ban user-- no such user (`'+options.userId+'`) exists!'); }
    
    User.update({id: options.userId}, {
      banned: true
    }).exec(function (err) {
      if (err) { return cb(err); }
      
      // If this user record does not currently have any connected sockets tracked, then that means he or she
      // does not have a live connection to our Sails app (via open browser tabs, iPhone apps, etc.).
      // So we can skip unsubscribing his or her sockets (since there aren't any).
      if (user.connectedSocketIds.length === 0) {
        return cb();
      }
      
      // On the other hand, if the user does have connected sockets, we will call `.leave()` for each one
      // to prevent it from receiving any messages from the "privateAdminRoom".
      async.each(user.connectedSocketIds, function eachSocketId (socketId, next) {
      
        // Note that `req` is not passed in-- instead we use a string socket id.
        // Since this is using a socket id explicitly, instead of inferring one from `req`,
        // we obviously don't have to check `isSocket`.
        sails.sockets.leave(socketId, 'privateAdminRoom', function(err) {
          if (err) {
            // If a socket cannot be unsubscribed, ignore it and continue on (but log a warning)
            sails.log.warn('Could not unsubscribe socket `'+socketId+'`.  Error:',err);
            return next();
          }
          
          return next();
        });
      }, function afterwards(err) {
        if (err) { return cb(err); }
        
        sails.log.info(
        'Sockets:`'user.connectedSocketIds+'` (probably open browser tabs) were kicked ',
        'from "privateAdminRoom" as a result of banning user (`'+options.userId+'`). '+
        'No more fun, ever!');
        
        return cb();
      });//</async.each>
    });//</User.update>
  });//</User.find>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment