简体   繁体   中英

How to get the socket object from within a post method in node.js?

In node.js, I have a server (express) set up like this

app.post('/request', function(req, res) {
    // TODO get socket, then do socket.emit('message', {});
    res.end();
});

and socket

var io = socket.listen(server);
io.on('connection', function(socket){
    console.log('Detected Request');
    socket.on('disconnect', function() {
        console.log('Request Finished');
    });
});

If there is a client, who connects to server first, making a socket, then does a POST for /request , how can I get the socket object for that client from within the post handler function?

Thanks

when you connect socket from the client you have to pass the user id along with socket and you have to catch it and use it to identify the socket for that user.

const socket = io();
io('/', { query: "id=user id here" });

Server side code here:

var connectedUsers = {};
var io = socket.listen(server);
io.on('connection', function(socket){
    var userId = socket.handshake.query['id'];
    var connectedUser = {id:userId, socket:socket}
    // every socket connection will have unique socket.id which we use to store in socket and identify if disconnected.
    connectedUsers[socket.id] = connectedUse
    socket.on('disconnect', function() {
        for(var i in connectedUsers)
        if(connectedUsers[i].socket.id === socket.id){
            delete connectedUsers[i];
        }
    });
});

Now in your post request you have to identify the user by the same id and get the respective socket for the user.

app.post('/request', function(req, res) {
    var userId = 'write your code to get user id';
    if(connectedUsers[userId])
    connectedUsers[userId].socket.emit('message', {});
    else
    console.log('User not online');
    res.end();
});

Note: this is just a sample will not work until you handle fetching user id properly.

If you can identify user only after login, you have to create a socket event for user login and emit user id to server from client and write 'connection' code inside the login event.

It is required to identify the client using a TCP message.

For testing, the file description can be used: req.socket.fd === socket.fd .

Remember, this is only applicable for one server since the http request may open another socket.

Buried in the socket.io documentation is sending mesagges from the outside world , and the suggest method is socket.io-emitter . I couldn't get it to work, and I think it's for broadcast only rather than to a specific client. Instead I exported sending functions in the io object from socket.js.

File app.js:

app.post('/request', function(req, res) {
  var clientid = //you need to capture the socket id you want at ****
                 //and pass it in the post body or cookie
  SOCKET.sendX(clientid, "my message");
  res.end();
});

var server = app.listen(8088);
var SOCKET = require("./socket")(server);

File socket.js:

module.exports = function(server) {

  var io = socket.listen(server);
    io.on('connection', function(socket){
      //****
      //here you have to save socket.id for use in your post method

      //the usual stuff
      socket.on('xxx', function() {
      }

      return {
        sendX: function send(socket, msg) {
              io.clients().connected[socket].emit("sendX", msg);
             }
      }
}

Side note: There is no need to maintain that connectedUsers variable in your original post as they are in io.clients().connected

My code worked quite well, but it was written in Typescript so there may be some errors as I translated it manually for this answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM