How to get current socket object or id with in a sails controller?

1.1k Views Asked by At

I would like to access the currently connected socket id with in a sails.js (v0.12 ) controller function. sails.sockets.getId(req.socket); is showing undefined since this is not a socket request

My objective is to set the online status of my user in the database when he logged in successfully

login: function (req, res) {

    Util.login(req, function(){
        var socketId = sails.sockets.getId(req.socket);
        console.log('socketId ===', socketId); // return undefined
    });
},

Basically i would like to access the current user's socket object in a controller or access current user's session object with in a socket on method

Also i'm not sure that how can i rewrite my old sockets.onConnect handler

 onConnect: function(session, socket) {
// Proceed only if the user is logged in

if (session.me) {
    //console.log('test',session);

    User.findOne({id: session.me}).exec(function(err, user) {
        var socketId = sails.sockets.getId(socket);

        user.status = 'online';
        user.ip = socket.handshake.address;

        user.save(function(err) {
          // Publish this user creation event to every socket watching the User model via User.watch()
          User.publishCreate(user, socket);
        });

        // Create the session.users hash if it doesn't exist already
        session.users = session.users || {};

        // Save this user in the session, indexed by their socket ID.
        // This way we can look the user up by socket ID later.
        session.users[socketId] = user;

        // Persist the session
        //session.save();

        // Get updates about users being created
        User.watch(socket);

        // Send a message to the client with information about the new user
        sails.sockets.broadcast(socketId, 'user', {
          verb :'list',
          data:session.users
        });
    });
}
},
1

There are 1 best solutions below

1
On

You need to pass the req object to the method.

if (req.isSocket) {
    let socketId = sails.sockets.getId(req);
    sails.log('socket id: ' + socketId);
}

Since the request is not a socket request, you might need to do something like

  • Send back some identifier to the client once logged in.
  • Use the identifier to join a room. (One user per room. )
  • Broadcast messages to the room with the identifier whenever you need to send message to client.

https://gist.github.com/crtr0/2896891

Update:

From sails migration guide

The onConnect lifecycle callback has been deprecated. Instead, if you need to do something when a new socket is connected, send a request from the newly-connected client to do so. The purpose of onConnect was always for optimizing performance (eliminating the need to do this initial extra round-trip with the server), yet its use can lead to confusion and race conditions. If you desperately need to eliminate the server roundtrip, you can bind a handler directly on sails.io.on('connect', function (newlyConnectedSocket){}) in your bootstrap function (config/bootstrap.js). However, note that this is discouraged. Unless you're facing true production performance issues, you should use the strategy mentioned above for your "on connection" logic (i.e. send an initial request from the client after the socket connects). Socket requests are lightweight, so this doesn't add any tangible overhead to your application, and it will help make your code more predictable.

// in some controller
if (req.isSocket) {
    let handshake = req.socket.manager.handshaken[sails.sockets.getId(req)];
    if (handshake) {
        session = handshake.session;
    }
}