Reputation: 886
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
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
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