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..

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Set your Twitter account name in your settings to use the TwitterBar Section.

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close