I want to create a user sessison when user enter the app. And read the session whenever needed. Here is my try
var io = require('socket.io'), express = require('express'); querystring = require('querystring'); var app = express.createServer(); app.get('/', function(req, res){ var sessionVal = querystring.parse(req.url.substr(2));// sessionVal is an email for example: [email protected] app.use(express.cookieParser()); app.use(express.session({ secret: sessionVal })); }); var socket = io.listen(app); socket.on('connection', function(client) { client.on('message', function(message) { // message will be an object {text:'user text chat blah blah', email:'[email protected]'} // if the seesion stored, has the same value with message.email // then the message will be broadcasted socket.broadcast(message.text); // else will not broadcast }); }); app.listen(4000);
In the following example, we will create a view counter for a client. var express = require('express'); var cookieParser = require('cookie-parser'); var session = require('express-session'); var app = express(); app. use(cookieParser()); app. use(session({secret: "Shh, its a secret!"})); app.
var cookieSession = require('cookie-session') var express = require('express') var app = express() app. use(cookieSession({ name: 'session', keys: ['key1', 'key2'] })) // Update a value in the cookie so that the set-cookie will be sent. // Only changes every minute so that it's not sent with every request. app.
Here, since sess is global, the session won't work for multiple users as the server will create the same session for all the users. This can be solved by using what is called a session store. We have to store every session in the store so that each one will belong to only a single user.
I need to point out here that you're incorrectly adding middleware to the application. The app.use
calls should not be done within the app.get
request handler, but outside of it. Simply call them directly after createServer
, or take a look at the other examples in the docs.
The secret you pass to express.session
should be a string constant, or perhaps something taken from a configuration file. Don't feed it something the client might know, that's actually dangerous. It's a secret only the server should know about.
If you want to store the email address in the session, simply do something along the lines of:
req.session.email = req.param('email');
With that out of the way...
If I understand correctly, what you're trying to do is handle one or more HTTP requests and keep track of a session, then later on open a Socket.IO connection from which you need the session data as well.
What's tricky about this problem is that Socket.IO's means of making the magic work on any http.Server
is by hijacking the request
event. Thus, Express' (or rather Connect's) session middleware is never called on the Socket.IO connection.
I believe you can make this work, though, with some trickery.
You can get to Connect's session data; you simply need to get a reference to the session store. The easiest way to do that is to create the store yourself before calling express.session
:
// A MemoryStore is the default, but you probably want something // more robust for production use. var store = new express.session.MemoryStore; app.use(express.session({ secret: 'whatever', store: store }));
Every session store has a get(sid, callback)
method. The sid
parameter, or session ID, is stored in a cookie on the client. The default name of that cookie is connect.sid
. (But you can give it any name by specifying a key
option in your express.session
call.)
Then, you need to access that cookie on the Socket.IO connection. Unfortunately, Socket.IO doesn't seem to give you access to the http.ServerRequest
. A simple work around would be to fetch the cookie in the browser, and send it over the Socket.IO connection.
Code on the server would then look something like the following:
var io = require('socket.io'), express = require('express'); var app = express.createServer(), socket = io.listen(app), store = new express.session.MemoryStore; app.use(express.cookieParser()); app.use(express.session({ secret: 'something', store: store })); app.get('/', function(req, res) { var old = req.session.email; req.session.email = req.param('email'); res.header('Content-Type', 'text/plain'); res.send("Email was '" + old + "', now is '" + req.session.email + "'."); }); socket.on('connection', function(client) { // We declare that the first message contains the SID. // This is where we handle the first message. client.once('message', function(sid) { store.get(sid, function(err, session) { if (err || !session) { // Do some error handling, bail. return; } // Any messages following are your chat messages. client.on('message', function(message) { if (message.email === session.email) { socket.broadcast(message.text); } }); }); }); }); app.listen(4000);
This assumes you only want to read an existing session. You cannot actually create or delete sessions, because Socket.IO connections may not have a HTTP response to send the Set-Cookie
header in (think WebSockets).
If you want to edit sessions, that may work with some session stores. A CookieStore wouldn't work for example, because it also needs to send a Set-Cookie
header, which it can't. But for other stores, you could try calling the set(sid, data, callback)
method and see what happens.
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