It was really easy setting up sessions and using them in PHP. But my website needs to deal with WebSockets. I am facing problem to set up sessions in node.js. I can easily push data without using sessions and it would work fine but when more than one tab is opened the new socket.id is created and previously opened tabs won't function properly. So I have been working on sessions and had problem accessing session store, its logging session not grabbed. I have tried with session.load as well but no luck
How do I get session object and use it in a way that opening other tabs wouldn't affect the functionality and push data from server to client on all tabs?
var express=require('express');
var http = require('http');
var io = require('socket.io');
var cookie = require("cookie");
var connect = require("connect"),
MemoryStore = express.session.MemoryStore,
sessionStore = new MemoryStore();
var app = express();
app.configure(function () {
app.use(express.cookieParser());
app.use(express.session({store: sessionStore
, secret: 'secret'
, key: 'express.sid'}));
app.use(function (req, res) {
res.end('<h2>Hello, your session id is ' + req.sessionID + '</h2>');
});
});
server = http.createServer(app);
server.listen(3000);
sio = io.listen(server);
var Session = require('connect').middleware.session.Session;
sio.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
data.cookie = connect.utils.parseSignedCookies(cookie.parse(data.headers.cookie),'secret');
// note that you will need to use the same key to grad the
// session id, as you specified in the Express setup.
data.sessionID = data.cookie['express.sid'];
sessionStore.get(data.sessionID, function (err, session) {
if (err || !session) {
// if we cannot grab a session, turn down the connection
console.log("session not grabbed");
accept('Error', false);
} else {
// save the session data and accept the connection
console.log("session grabbed");
data.session = session;
accept(null, true);
}
});
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
sio.sockets.on('connection', function (socket) {
console.log('A socket with sessionID ' + socket.handshake.sessionID
+ ' connected!');
});
Take a look at this article: Session-based Authorization with Socket.IO
Your code works fine, but need 2 improvements to do what you want (send session data to clients from server):
sessionID
during authorization onlysessionID
during connection where you can send data from server to clients in an interval.Here's the improved code:
var express = require('express');
var connect = require('connect');
var cookie = require('cookie');
var sessionStore = new express.session.MemoryStore();
var app = express();
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.session({store: sessionStore, secret: "secret", key: 'express.sid'}));
// web page
app.use(express.static('public'));
app.get('/', function(req, res) {
var body = '';
if (req.session.views) {
++req.session.views;
} else {
req.session.views = 1;
body += '<p>First time visiting? view this page in several browsers :)</p>';
}
res.send(body + '<p>viewed <strong>' + req.session.views + '</strong> times.</p>');
});
var sio = require('socket.io').listen(app.listen(3000));
sio.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
var rawCookies = cookie.parse(data.headers.cookie);
data.sessionID = connect.utils.parseSignedCookie(rawCookies['express.sid'],'secret');
// it checks if the session id is unsigned successfully
if (data.sessionID == rawCookies['express.sid']) {
accept('cookie is invalid', false);
}
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
sio.sockets.on('connection', function (socket) {
//console.log(socket);
console.log('A socket with sessionID ' + socket.handshake.sessionID + ' connected!');
// it sets data every 5 seconds
var handle = setInterval(function() {
sessionStore.get(socket.handshake.sessionID, function (err, data) {
if (err || !data) {
console.log('no session data yet');
} else {
socket.emit('views', data);
}
});
}, 5000);
socket.on('disconnect', function() {
clearInterval(handle);
});
});
Then you can have a client page under public/client.html
at http://localhost:3000/client.html
to see the session data populated from http://localhost:3000
:
<html>
<head>
<script src="/socket.io/socket.io.js" type="text/javascript"></script>
<script type="text/javascript">
tick = io.connect('http://localhost:3000/');
tick.on('data', function (data) {
console.log(data);
});
tick.on('views', function (data) {
document.getElementById('views').innerText = data.views;
});
tick.on('error', function (reason){
console.error('Unable to connect Socket.IO', reason);
});
tick.on('connect', function (){
console.info('successfully established a working and authorized connection');
});
</script>
</head>
<body>
Open the browser console to see tick-tocks!
<p>This session is viewed <b><span id="views"></span></b> times.</p>
</body>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With