David Walsh Blog

WebSocket and Socket.IO

My favorite web technology is quickly becoming the WebSocket API. WebSocket provides a welcomed alternative to the AJAX technologies we’ve been making use of over the past few years. This new API provides a method to push messages from client to server efficiently and with a simple syntax. Let’s take a look at the HTML5 WebSocket API: its use on the client side, server side, and an outstanding wrapper API called Socket.IO.

What is the WebSocket API?

The WebSocket API is the next generation method of asynchronous communication from client to server. Communication takes place over single TCP socket using the ws (unsecure) or wss (secure) protocol and can be used by any client or server application. WebSocket is currently being standardized by the W3C. WebSocket is currently implemented in Firefox 4, Chrome 4, Opera 10.70, and Safari 5.

What’s great about the WebSocket API that server and client can push messages to each other at any given time. WebSocket is not limited in its nature the way that AJAX (or XHR) is; AJAX technologies require a request to be made by the client, whereas WebSocket servers and clients can push each other messages. XHR is also limited by domain; the WebSocket API allows cross-domain messaging with no fuss.

AJAX technology was a clever usage of a feature not designed to be used the way it is today. WebSocket was created for the specific purpose of bi-direction message pushing.

WebSocket API Usage

Focusing on the client side API only (because each server side language will have its own API), the following snippet opens a connection, creates event listeners for connect, disconnect, and message events, sends a message back to the server, and closes the connection.

// Create a socket instance
var socket = new WebSocket('ws://localhost:8080');

// Open the socket
socket.onopen = function(event) {
	// Send an initial message
	socket.send('I am the client and I\'m listening!');
	// Listen for messages
	socket.onmessage = function(event) {
		console.log('Client received a message',event);
	// Listen for socket closes
	socket.onclose = function(event) {
		console.log('Client notified socket has closed',event);
	// To close the socket....

Let’s take a look at the individual pieces of the snippet above. The argument provided to WebSocket represents the URL to the address listening for socket connections. onopen, onclose, and onmessage methods connect you to events on the socket instance. Each of these methods provides an event which gives insight as to the state of the socket.

The onmessage event provides a data property which contains the body of the message. The message body must be a string, so serialization/deserialization strategies will be needed to pass more data.

The syntax is extremely simple which makes using WebSockets incredibly easy…unless the client doesn’t support WebSocket. Internet Explorer does not currently support WebSocket. There are a few fallback transports that you can use if the client doesn’t support WebSocket:

Wouldn’t it be great if an API was available that would provide WebSocket event handling, fallback transports, and a server side solution, all within one API? Luckily Guillermo Rauch has created Socket.IO.

WebSocket with Socket.IO

Socket.IO is a WebSocket API created by Guillermo Rauch, CTO of LearnBoost and lead scientist of LearnBoost Labs. Socket.IO will use feature detection to decide if the connection will be established with WebSocket, AJAX long polling, Flash, etc., making creating realtime apps that work everywhere a snap. Socket.IO also provides an API for Node.js which looks very much like the client side API.

Client – Socket.IO Setup

Socket.IO is available for download at GitHub. You can include the socket.io.js file or you can pull Socket.IO from CDN:

<script src="http://cdn.socket.io/stable/socket.io.js"></script>

With Socket.IO available in the page, it’s time to create a Socket:

// Create SocketIO instance, connect
var socket = new io.Socket('localhost',{
	port: 8080

// Add a connect listener
socket.on('connect',function() {
	console.log('Client has connected to the server!');
// Add a connect listener
socket.on('message',function(data) {
	console.log('Received a message from the server!',data);
// Add a disconnect listener
socket.on('disconnect',function() {
	console.log('The client has disconnected!');

// Sends a message to the server via sockets
function sendMessageToServer(message) {

Socket.IO simplifies the WebSocket API and unifies the APIs of its fallback transports. Transports include:

You may set any of the Socket.IO instance’s options with a second argument to the constructor. Options include:

Socket.IO also provides the usual connect, disconnect, and message events that the native WebSocket API provides. Socket also provides an on method which wraps each event type, much the way Node does.

Node.js – Socket.IO Setup

The server side solution provided by Socket.IO allows unification of the client and server side APIs. With Node, you create a typical HTTP server but then pass the server instance to SocketIO. From there, you create connection, disconnect, and message listeners much the way you did on the client side.

A sample server side script would look very much like this:

// Require HTTP module (to start server) and Socket.IO
var http = require('http'), io = require('socket.io');

// Start the server at port 8080
var server = http.createServer(function(req, res){ 

	// Send HTML headers and message
	res.writeHead(200,{ 'Content-Type': 'text/html' }); 
	res.end('<h1>Hello Socket Lover!</h1>');

// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);

// Add a connect listener
socket.on('connection', function(client){ 
	// Success!  Now listen to messages to be received
		console.log('Received message from client!',event);
		console.log('Server has disconnected');


You can run the server portion (assuming you have Node.js installed) from command line with:

node socket-server.js

Now your client and server can push messages back and forth! Within the Node.js script, you can create a periodical message sender using some simple JavaScript:

// Create periodical which ends a message to the client every 5 seconds
var interval = setInterval(function() {
	client.send('This is a message from the server!  ' + new Date().getTime());

The server side script will push a message to the client every five seconds!

dojox.Socket and Socket.IO

Persevere creator Kris Zyp has created dojox.Socket. dojox.Socket wraps the WebSocket API in an API consistent with Dojo and provides a long-polling alternative if the client doesn’t support WebSocket. Here’s how you can use dojox.Socket on the client side and Socket.IO on the server side:

var args, ws = typeof WebSocket != 'undefined';
var socket = dojox.socket(args = {
	url: ws ? '/socket.io/websocket' : '/socket.io/xhr-polling',
	transport: function(args, message){
		args.content = message; // use URL-encoding to send the message instead of a raw body
var sessionId;
socket.on('message', function(){
	if (!sessionId){
		sessionId = message;
		args.url += '/' + sessionId;
	}else if(message.substr(0, 3) == '~h~'){
		// a heartbeat

dojox.socket.Reconnect has also been created to automatically reconnect if the socket loses connection. Look forward to dojox.Socket debuting in Dojo 1.6.

Practical Applications

There are many practical applications for WebSocket. WebSocket is ideal for most client-to-server asynchronous purposes, chat within the browser being the most prominent. WebSocket is used to day by most many companies because of its efficiency. Socket.IO is in use by many organizations and was very popular at the Node KnockOut contest.

WebSocket Resources

There’s not a great deal of information available about WebSocket so I’ve rounded up a few helpful resources:

Take a moment to download my demo and visit the resources provided above. The WebSocket API is the future of asynchronous messaging; Socket.IO is the best available resource for WebSocket in Node.js and within the browser. Let me know your thoughts on WebSocket as I’m curious to know if you’re as excited as I am by this new API!