Socket.IO and IIS
WebSockets are pretty great. I won't go into too much detail here, but the low-latency persistent connections that WebScokets provide have a temendous potential for boosting many web applications.
Unfortunately, browser support for WebSockets is still spotty, although we've had the basic building blocks for providing WebSocket-like functionality for some time now. Socket.IO patches those building blocks together, and provides WebSocket-like functionality on just about any browser imaginable.
As it turns out, a few servers also don't quite support WebSockets yet. Long story, but until the Windows world migrates to IIS 8, there's also no WebSocket support in IIS. Fortunately, the Socket.IO's Node.js-based server component lets us use AJAX Long Polling to simulate the same functionality, with WebSocket-like semantics. It's not perfect, but it works, and be modified to use actual WebSockets with almost no code changes (once you get a server that supports "real" WebSockets).
In any event, if you're stuck with IIS 7.5, you can still use Socket.IO today. This isn't particualrly well-documented, and there are some needlessly complicated workarounds floating around, so here's how you should do it:
- Install Node and iisnode. (More on that here)
- In your node application's folder, grab socket.io with npm:
npm install socket.io
- Create your Socket.IO server application, and a client. Be sure to configure Socket.IO with a
resource
parameter on both your client and server.
Here's a barebones example to get you started. In practice, you'll probably want to use URL rewriting (and Express) so you can also serve up other content.
On the server (myApp/server.js
):
var app = require('http').createServer(handler),
io = require('socket.io').listen(app);
io.configure(function(){
io.set('transports',['xhr-polling']); //Use long-polling instead of websockets!
io.set('resource','/myApp/server.js'); //Where we'll listen for connections.
});
app.listen(process.env.PORT);
function handler(req,res){
/*
* Your code for handling non-websocket requests...
* Note that Socket.IO will intercept any requests made
* to myApp/server.js without calling this handler.
*/
}
io.sockets.on('connection', function (client) {
console.log("New Connection");
client.on('message',function(message,callback){
console.log("Message Received");
client.emit('response',"Got it!");
}
}
And on the client (which can be hosted anywhere):
<script src="/path-to-socket.io-client/socket.io.js"></script>
<script type="application/javascript">
var socket = io.connect('http://myServer',{resource: 'myApp/server.js'}); //Same resource as the server. socket.on('response',
function (msg) { console.log("Message received:",msg); });
socket.emit('message','hi');
</script>
In practice, you'll probably want to set up URL rewriting to rewrite requests for anything inside /myApp/*
to server.js
. In my case, I rewrite myApp/socket
to server.js
in web.config
, and specify myApp/socket
as the resource
parameter on both the client and server.