Andrew
Andrew

Reputation: 886

How to detect multiple socket.io connections from same user

I have followed this guide: http://www.danielbaulig.de/socket-ioexpress/ to link express.js to socket.io and it works brilliantly.

I have the user logging in on one page (express.js POST request that sets a session object) and when they have authenticated it directs them to a new page where socket.io loads and on the server socket.io can grab the session that was set from express. So that all works fine.

Now I have users on the page that uses socket.io and when that page is refreshed - sometimes the socket.io connection is still there (ie. it doesn't disconnect). What I am trying to do is alter the io.set('authorization') function to ensure that when the user connects - it will disconnect all existing socket.io instances that are still open to that client.

Here is the how it looks at the moment:

//socket.io connect to express
var parseCookie = require('connect').utils.parseCookie;
io.set('authorization', function (data, accept) {
    if (data.headers.cookie) 
    {
        data.cookie = parseCookie(data.headers.cookie);
        data.sessionID = data.cookie['express.sid'];
        // (literally) get the session data from the session store
        sessionStore.get(data.sessionID, function (err, session) 
        {
            if (err || !session) 
            {
                // if we cannot grab a session, turn down the connection
                //note: a session is created when the user logs in
                accept('Error', false);
            } 
            else 
            {
                //TODO something here before we accept the connection
                //??

                // save the session data
                data.session = session;
                //accept the connection
                accept(null, true);
            }
        });
    } 
    else 
    {
        return accept('No cookie transmitted.', false);
    }
});

How do I check if the client that is about to be accepted has a previous connection, and it is still open (and therefore we need to disconnect that old one).

The express session has a "username" in it - so we can get the session object and get the username, I just can't figure out how to go through the list of all the socket.io clients and have a look at the express session for each one and check if it the same as the user authenticating currently.

Upvotes: 14

Views: 7922

Answers (2)

saeta
saeta

Reputation: 4238

There are a lot of code on Socket.IO has been old.

The new documentation (Socket.IO 1.3.6, right now), says:

"The old io.set () and io.get () methods are deprecated and only supported for backwards compatibility. Here is a translation of an example authorization old-style into middleware." in the section "Migration from 0.9"

If you use a new version of Socket.IO. The code you need is something like:

    var sessionStore    = new MongoStore({ url: config.db });
    var cookie          = require('cookie-parser')("SECRET");
    io.use(function(socket, callback) {
        if (socket.request.headers.cookie) {
            cookie(socket.request, null, function(err) {
                sessionStore.get(socket.request.signedCookies["connect.sid"], function(err, session) {
                    if (err || !session) {
                      callback('Session error', false);
                    } else {
                      socket.request.sessionID = socket.request.signedCookies["connect.sid"];
                      console.log(socket.request.sessionID);
                      callback(null, true);
                    }
                  });
            });
        }
        else {
            return callback('No session.', false);
        }
    });
    io.on('connection', function(socket) {
        console.log(socket.request.sessionID);
    });

Upvotes: 0

Tony Abou-Assaleh
Tony Abou-Assaleh

Reputation: 3040

In my application, I explicitly manage the socket.io sessions. On the server side, whenever a new connection is established, I do something like: socketio_session[user_id].push(session). This gives me access to all the sessions connected for a particular user. In your case, you may not need to store a list of sessions per user, but only store the latest session and onconnect force disconnect on the existing session, if any, before storing the new session.

Upvotes: 7

Related Questions