There is something visceral to code a server and getting it to run. node.js is just that, an unassuming ferocity that draws developers in.
The Node beginner book – http://www.nodebeginner.org/, helps developers take the first baby steps.
This post is meant for people who have gone past that and want to do a realtime socket.io program.
Why socket.io – Ever wanted to send realtime data to all the people connected in any language – its like walking on broken glass. You have solutions like cometd or mq, which involves setting up an application on the server and then setting up something on the client and then figuring why your config doesn’t work, or it’s only supported on 1 platform *shudder*
What we are going to do here is put together a simple program to send time to all the clients connected to the server – with very few lines of code. I have assumed you have installed node.js already and rubbing your hands together… and created an empty directory to get started.
I have used the directory created is called /tmp/foo
First you will need to install socket.io and express
cd /tmp/foo npm install express socket.io
You should see
npm http GET https://registry.npmjs.org/express npm http GET https://registry.npmjs.org/socket.io . . express@2.5.2 ./node_modules/express ├── mkdirp@0.0.7 ├── qs@0.4.0 ├── mime@1.2.4 └── connect@1.8.5 socket.io@0.8.7 ./node_modules/socket.io ├── policyfile@0.0.4 ├── redis@0.6.7 └── socket.io-client@0.8.7
Nice and dandy, you should see under /tmp/foo a directory called node_modules with socket.io and express
parj@ubuntu:/tmp/foo$ ll node_modules/ total 20 drwxr-xr-x 5 parj parj 4096 2011-12-25 14:44 ./ drwxr-xr-x 3 parj parj 4096 2011-12-25 14:44 ../ drwxr-xr-x 2 parj parj 4096 2011-12-25 14:44 .bin/ drwxr-xr-x 6 parj parj 4096 2011-12-25 14:44 express/ drwxr-xr-x 7 parj parj 4096 2011-12-25 14:44 socket.io/
But wait, what if you have several projects and all using socket.io and express. If any component gets updated how are you going to deal with that? Update every project individually. There is a better solution – use npm link.
NOTE:This section about symbolic linking does not work on Windows – This is because the file system does not support symbolic links.
npm install -g socket.io express #Install globally cd /tmp/foo rm -rf node_modules npm link express socket.io
Now if you do a listing, it shows that symbolic links have been created for the modules
parj@ubuntu:/tmp/foo$ ll node_modules/ total 12 drwxr-xr-x 3 parj parj 4096 2011-12-25 14:48 ./ drwxr-xr-x 3 parj parj 4096 2011-12-25 14:48 ../ drwxr-xr-x 2 parj parj 4096 2011-12-25 14:48 .bin/ lrwxrwxrwx 1 parj parj 52 2011-12-25 14:48 express -> /opt/node/lib/node_modules/express/ lrwxrwxrwx 1 parj parj 54 2011-12-25 14:48 socket.io -> /opt/node/lib/node_modules/socket.io/
Create server.js under /tmp/foo and paste the following – Code is also available on https://github.com/parj/node-websocket-demo
Tip: For copying and pasting code, just hover over the code you should see <> sign, click that and that will popup a dialog with unescaped HTML code, so when you copy & paste, there are no surprises
var http = require('http'),
io = require('socket.io'),
sys = require('sys'),
express = require('express');
var port = 8111; //The port to listen on
var server = express.createServer(); //Create server app
server.use(express.static(__dirname + '/public')); //The directory in which static files would be stored, js, images
server.use(express.errorHandler({showStack: true, dumpExceptions: true})); //Show exceptions
server.listen(port); //Start the server
var socket = io.listen(server); //socket.io listen
//When a client connects
socket.sockets.on('connection', function(client){
//Set connected flag true
var connected = true;
//Upon receiving a message type it out to the console
client.on('message', function(m){
sys.log('Message received: '+m);
});
//Upon disconnecting set connected flag to flase
client.on('disconnect', function(){
connected = false;
});
//Get the time every second and publish
var tick = function(){
if (!connected) {
return;
}
var dateTime = new Date();
var msg = dateTime.getHours() + ":" + dateTime.getMinutes() + ":" + dateTime.getSeconds();
console.log("Sending " + dateTime);
client.send(msg); //Send using socket.io to the client
setTimeout(tick, 1000); //Wait 1 second before redoing
};
tick();
});
Create a folder called public under /tmp/foo and under that create main.js – the client which will connect and get the messages
var socket = io.connect(); //Can be left blank as host and port will be autodetected
socket.on('connect', function(){
$('#status').text('Connected');
});
socket.on('message', function(m){
$('#message').text(m);
});
socket.on('disconnect', function(){
$('#status').text('Disconnected');
});
Create under /tmp/foo/public, index.html
<!DOCTYPE html>
<html>
<head>
<script src="/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="/main.js"></script>
</head>
<body>
<h1>WebSocket Test</h1>
<h2>Status: <span id="status">Waiting</span></h2>
<pre id="message"></pre>
</body>
</body>
Finally, download jquery and place the file in /tmp/foo/public – ensure the file is named jquery.min.js.
….
Start the server
cd /tmp/foo node server.js
You will get
parj@ubuntu:/tmp/foo$ node server.js The "sys" module is now called "util". It should have a similar interface. info - socket.io started
Open a browser (Chrome, Firefox) and head to http://localhost:8111/
On the server you should see
parj@ubuntu:/tmp/foo$ node server.js The "sys" module is now called "util". It should have a similar interface. info - socket.io started debug - client authorized info - handshake authorized 1465125961783431727 debug - setting request GET /socket.io/1/websocket/1465125961783431727 debug - set heartbeat interval for client 1465125961783431727 debug - client authorized for debug - websocket writing 1:: Sending Sun Dec 25 2011 16:45:30 GMT+0000 (GMT) debug - websocket writing 3:::16:45:30 Sending Sun Dec 25 2011 16:45:31 GMT+0000 (GMT) debug - websocket writing 3:::16:45:31 Sending Sun Dec 25 2011 16:45:32 GMT+0000 (GMT) debug - websocket writing 3:::16:45:32 Sending Sun Dec 25 2011 16:45:33 GMT+0000 (GMT) debug - websocket writing 3:::16:45:33
On the client in the browser, you should see status connected and the time moving
WebSocket Test Status: Connected 16:46:20
If you want to check out the code and play around with it
git clone git://github.com/parj/node-websocket-demo.git
PS: Please note no badgers where harmed in writing this code…
PPS: The same could not be said for the keyboard and the network packets involved..





