0

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

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

Can you expand more on Remember, this is only applicable for one server since the http request may open another socket. ?
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.