3
votes

Im creating a simple socket.io chat that uses passport.js for authentication. But everytime a user logout and login the old socket connection reconnects. This causes a problem because now there are two active connections to one page. So what I want to do is end the current connection when the user navigates to "/logout".

var socketNotLoaded = true;
var socket;

app.get('/', function(req, res) {
    if (req.isAuthenticated()) {
        if(socketNotLoaded) { //is true when new connection is required
            require("./socket")(io,req.user) //runs the socket.io script
            socketNotLoaded = false;
        }
        res.render('index', pug.get(req.user));
    } else {
        res.render('notloggedin', pug.get());
    }
})

app.get('/logout', function(req, res) {
    socketNotLoaded = true;
    req.logout();
    res.redirect('/');
})

Im using

  • socket.io: 2.0.3
  • passport: 0.4.0
  • passport-local: 1.0.0
  • express: 4.15.4
  • express-session: 1.15.5
  • cookie-parser: 1.4.3
  • body-parser: 1.17.2
1
Apparently you have client code in your web pages that is reconnecting after you logout and reconnect. That's likely where the problem is. Plus, your code appears to be designed only for one user. If if(socketNoLoaded) call is using a module level variable to decide whether to initialize socket.io with req.user. That just doesn't make sense. What do you expect to happen when the second user comes to your site? Or the third user? - jfriend00
Oh I see. How should I fix that? - Rasmus Nilsson
Honestly, I don't understand what you're trying to do. Your current design looks to me to be fundamentally flawed. Per-user state needs to be in your session, not in module level variables. The socket.io server should be initialized when the server starts up and at the same time your web server is initialized. It should always be running and it should not be initialized with any per-user state. You don't make a new socket.io server for each user, you have ONE socket.io server that all users use (just like your web server). - jfriend00
Thank you, now it makes more sense. But how would I then securely give socket.io the active users details? - Rasmus Nilsson
I don't know what "give it the active users details" means? What are "active users details" and why are you wanting to give them to the socket.io server? - jfriend00

1 Answers

0
votes

On the client-side when the user wants to logout, you could perform a socket.emit('exit');, then on the server-side have a listener like so:

socket.on('exit', function(){
    socket.disconnect();
});

And that will disconnect the client from Socket.io. You could also create an object on the server-side that maps a username to a Socket.io socket ID, and perform a check to see if that user already exists. If it does, then you can disconnect that socket ID on the server-side. Ideally, the client should send a disconnect to the server when the user logs out. Something like this:

 $('#logout').click( function() {
            socket.disconnect();
            window.location = "/logout";
});