occasionally useful ruby, ubuntu, etc

30Oct/112

Sharing session state in Node.js between your HTTP server and websockets server

At first, sharing your session state between your Node.js HTTP server and websockets server might seem difficult. However, if you're using Express and NowJS (or the technologies they're built on, Connect and Socket.IO, respectively), most of the work has already been done for you -- it's just a matter of connecting the right pieces together. An example follows, written in Coffeescript.

There are three parts: fixing your session store, fixing your web sockets code, and fixing your HTTP application code.

Fixing your session store

Before, for Express (or Connect), you might have something like this:

1 2 3 4
app.configure ->
# ...
app.use express.session({secret: "my_super_secret"})
# ...

When instead, you want something like this:

1 2 3 4 5
{MemoryStore} = require('connect').session
sessionStore = new MemoryStore
 
app.configure ->
app.use express.session({secret: "my_super_secret", store: sessionStore})

This will allow you to access the session store directly from outside Express/Connect's callbacks.

If you look at the source for Connect's sessions here, you can see this is essentially the same as what the default behavior is. Also, if you're already using an alternative store (i.e. Redis store), the only thing you have to do is make sure you're creating a variable for the store in a scope broad enough for the relevant parts of your application.

Fixing your websockets code

This is fairly straightforward if you know where to look, but NowJS/Socket.IO automatically send a user's cookies. Here's how you use them to access the user's session:

1 2 3 4 5
everyone.now.playerJoined = () ->
sid = unescape(@user.cookie["connect.sid"]) # you DO have to unescape the session id!
sessionStore.get(sid, (err, sess) ->
console.log("That player who joined? his userId is #{sess.userId}")
)

Fixing your HTTP application code

Ha, I lied, there is no third part. You can keep accessing cookies and sessions in your application the exact same way as you were before. req.session will still be automatically populated with the user's session, retrieved from the session store.

Conclusion

Hope this helps someone out! It seems obvious in retrospect, but figuring out exactly how to share state is a little tricky.

Comments (2) Trackbacks (0)
  1. This is exactly the help I was looking for (I think), so thanks a lot for such a useful post. Am I correct in thinking you need to install and require connect for this to work?

    • Well…you need to be able to instantiate your session store manually, wherever it is. In the case of Express, you’ll already have Connect installed since Express is built on top of Connect. This is really just a guide on how to create that session store manually, so that you can grab it in the right scope so you can share it. Does that answer your question?


Leave a comment


No trackbacks yet.