Wednesday, October 22, 2014

Socket.io with Express

Today I introduced the world to 2-player Solitaire. It was the joke in today's comic, but I thought that it might work in real life too. At the very least, it helps add dimension to the joke.

In it, you and a friend are looking at the same card table. For each valid card placement, you get 1 point. Your goal is to put the cards on valid placements before your opponent does and thereby score the most points.

I've been working on it for about 3 weeks now, which is why I haven't had time to put much code in this blog. But now that it's ready (don't hesitate to send a bug report if you find anything weird) I have time to talk about different parts of it on a technical level.

It is a web application, using just HTML5 and JavaScript. It is playable on both mobile devices and your desktop. Since the main premise is a shared game board, I used Node and Socket.io to share the real-time game data between two web browser clients. I've been using Socket.io for years now, but this was only the second time I've used the 1.0 release combined with the Express framework. The first time I struggled with some things, so I thought I'd share the basic application outline that I came up with to make your life easier.

I'm using Express 4.8.7 and Socket.io 1.0.6 in this project. To set up your application to handle both "normal" HTTP traffic and the various Socket.io communication types, you have to deviate slightly from a typical Node/Express setup.

var express = require("express");
var http = require("http");

var app = express();
var server = http.Server(app);
var io = require("socket.io")(server);

//------------ Socket.io stuff

io.on("connection", function(socket) {
 
    // set up handlers for different events here
    socket.on("some_event", function(data) {
        // do something
    });

});

//------------ web application routes

app.get("/some/path", function(req, res, next) {
 
    res.send("some response");
 
});

// ------------ start the listening

var srv = server.listen(5000, function() {
    console.log("listening on port %d", srv.address().port);
});

The main difference between this configuration and a more typical Express app is what you see on line 4. You have to require the "http" module explicitly, and use it to create a Server instance using your Express app instance. You then pass that Server to Socket.io as I do on line 6.

After that, use your io and app objects to set up your application behavior via event handlers and routes. At the end, start your Server listening. Note that on line 29, it is the http server instance you use to start the listening instead of the Express app object.

Try that, and you're off to a good start. As always, the source code for the entire game is available on GitHub. Check it out if you want to see how I did everything else, or keep reading here and I'll talk about other parts of it soon.

Amphibian.com comic for 22 October 2014