May 012011
 
Deprecation Notice: Socket.io is now at version v0.7+. The content in this tutorial applies only to Socket.io v0.6. If you are using Socket.io v0.7 or above, see this version of the tutorial.

In my last post I went through installation and setup of some great new tools: node.js and socket.io. Now that we have node and socket.io installed, its time to play around a bit to understand how to use these new toys. In this post I’ll be writing a simple http server and some client-side html/javascript to go with it. (Note: I’m assuming readers have a basic understanding of html and javascript)

My goal here is to go step by step, to see each piece fit together. People more experienced with client/server programming concepts may want to skim a little. You can also download the test code created here as files at the bottom of the post.

As a sanity check, make sure node is installed and in your path by typing

node -v

You should see something like

   

Now we’re ready to write some code. Let’s start with the server. Navigate to the directory you want to test out of, and make a file called server_test.js for your test server:  

touch server_test.js

Open this file in your favorite text editor. Start by defining some variables at the top:  

var http = require('http'),
url = require('url'),
io = require('/usr/local/lib/node/socket.io'),
server;

We’re only including the bare essentials here, enough to start our server, receive requests, and use socket.io (we won’t even use socket.io yet, but we’ll get to that soon). Now let’s define the server  

server = http.createServer(function(req, res){ 
  // server code 
  var path = url.parse(req.url).pathname; 
  switch (path) {
    case '/': 
      res.writeHead(200, {'Content-Type': 'text/html'}); 
      res.write('Hello!\n'); 
      res.end(); 
      break; 
    default: send404(res); 
  } 
}), 

send404 = function(res){ 
  res.writeHead(404); 
  res.write('404'); 
  res.end(); 
}; 

server.listen(8080);

Ok, check out the block of code. We are creating an http server object by instantiating that server variable we defined above using the http library. We are then defining its behavior by parsing any urls it receives and throwing the path of the url into a switch/case statement. Notice that we could define this behavior based on anything we wanted, not necessarily the url path. Here we have just defined a case for path ’/', so our server will only respond to requests to the root path. For these requests, it will send “Hello!” back to the client. For all requests to other paths, we have defined the send404 function, which will return 404 to the client. We will add more path handling as we go on.

Finally, we have told our server to listen on port 8080. Now, fire up the server!  

node server_test.js

Want to master Node.js? Try my highly-rated online course Learn Node.js by Example. Click here to get 50% off on screencasts, interactive projects, and more!

You won’t see any output in the server terminal window, but the server is now running. Bring up a second terminal window to issue some requests to test the server. In a second command window, send a root request to the server with

curl localhost:8080

You should get a response similar to:

 

I’m using this snazzy blue terminal window for client-side commands, and sticking with green-on-black window for server output. Now we know our server can respond. Huzzah! Celebrate as necessary, and then its time to move on to bigger and better things. This server doesn’t do much, and our client is just a command line. Let’s start by adding some functionality to our server, courtesy of socket.io.

var http = require('http'),
url = require('url'),
fs = require('fs'),
io = require('/usr/local/lib/node/socket.io'),
server;

server = http.createServer(function(req, res){ 
  // your normal server code 
  var path = url.parse(req.url).pathname; 

  switch (path) {
    case '/': 
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write('&lt;h1>Hello! Try the <a href="/socket-io_test.html">Socket.io Test</a></h1>');
      res.end(); 
      break; 
    case '/socket-io-test.html': 
      fs.readFile(__dirname + path, function(err, data) { 
        if (err) return send404(res); 
        res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'}) 
        res.write(data, 'utf8'); 
        res.end(); 
      }); 
      break; 
    default: send404(res); 
  } 
}), 

send404 = function(res) { 
  res.writeHead(404); 
  res.write('404'); 
  res.end(); 
};

server.listen(8080); 

// socket.io, I choose you 
var io = io.listen(server); 
io.on('connection', function(client){ 
  // now we have a client object! 
  console.log("Connection accepted."); 
  client.on('message', function(message){ 
    console.log("Recieved message: " + message + " - from client " + client.sessionId); 
  }); 
  client.on('disconnect', function(){ 
    console.log("Connected " + client.sessionId + "terminated."); 
  }); 
});

We’ve added quite a few things here, let’s take stock. First, I’ve required the fs library, to access to some file I/O functions. I’ve also changed the response values to html, since this is an http server, after all. I’ve also created a path for a socket-io-test.html page, which I’ll create next, and put a link to that page in the response for the root path.

Most importantly, I’ve added some socket.io code, which you can see at the bottom of the page. First, we tell socket.io to listen to our server object. Now it has access to all traffic coming over that server, and can perform tasks based on it. Then I just tell socket.io what to do for the various events it will encounter: ‘connection’, ‘message’, and ‘disconnect’. In this case, I’m just going to have it send some output to the console logs that we can follow. Clean and simple, right? That’s the beauty of socket.io. Now I have to write that client socket-io-test.html page I’ve lead everyone to believe exists. Ok, I can man up. Here goes:

<h1>Socket.io Test</h1>
<div>
  <p id="status">Waiting for input</p>
</div>

<button id="connect" onclick="connect()">Connect</button>
<button id="disconnect" onclick="disconnect()">Disconnect</button> 
<button id="send" onclick="send()">Send Message</button>

Take a look at the html/javascript above. First, on the html side, we just have three buttons and a div. These will perform standard actions from client to server. The div is for displaying status from our socket.io object. In javascript, we’ve defined a client-side socket.io object, which looks like:

new io.Socket(host, [options]);

Since we are using localhost, we pass in null for the host parameter. We could also pass in ‘localhost’ to achieve the same effect. We then define behaviors of the socket object using

socket.on(action, function() )

For example,

socket.on('connect', function(){ status_update("Connected"); });

which calls our status_update javascript function when the socket connects. Ok, time for a test. Start your node server again, to get all of the changes we made (shut it down if it was still running, then restart). Check the server command line – since we now have socket.io running on the server, startup output should look something like

 

Open up a browser and go to http://localhost:8080.  You will see

Theres the link we added to the root path server response of the server – click it to go to the socket.io test page we just finished. You should see:

 

Now click the Connect button. You will see “Waiting for input” change to “Connected”, meaning our socket.on(‘connect’) function was invoked. Go back to the server terminal window:

  We can see that the connection was initiated via websocket, and the server has assigned me a client session id. Since its socket.io, the connection could have been initiated via nay number of technologies, depending on my browser and network situation. Go ahead and try out the Disconnect and Send Message buttons as well, which will also show output on the server

  The above output is the result of disconnecting our initial session, connecting again (note the new client session id), and sending a message of “Hello Server!”.

That’s it! Now you have a working socket.io server and a client page to interact with it. We’ve gone through the basics of client/server communication, and you should be able to expand this example code into something much more functional with a little javascript.  

Download Files:

socket-io-demo.zip

  • Pingback: Codehenge » Blog Archive » Getting Started With node.js and socket.io – Part 1

  • http://www.facebook.com/profile.php?id=1491961761 Alex Oshchepkov

    if you do npm install socket.io is installes socket.io in current_folder/node_modules/socket.io

    so it won’t find it in /usr/local/lib/node/socket.io

    You didn’t mention it in part1

    • Anonymous

      Ya, I should make a note of the version I was using. Things have changed a bit since npm v0.3.18, which is what I was using when that tutorial was made.

      Thanks for the note!

  • Spencer

    I start up the node server_test.js

    ————————————————–
    Spencers-MacBook-Pro:examples spencer$ node server_test.js
    info – socket.io started
    debug – served static /socket.io.js
    ————————————————–

    And open http://localhost:8080
    ..click the link but the last page with the connection button doesn’t seem to do anything

    How do I get the page to start sending information?

    • http://www.codehenge.net Constantine Aaron Cois

      When you click the ‘Connect’ button, do you see this message in the server terminal?:

      2 Aug 20:07:57 – Initializing client with transport “websocket”
      2 Aug 20:07:57 – Client 7028937395662069 connected
      Connection accepted.

      • Spencer

        Actually I changed the code, now it works with..

        var io = require(‘socket.io’).listen(server);

        io.sockets.on(‘connection’, function (socket) {
        socket.on(‘message’, function (message) {console.log(“Recieved message: ” + message);});
        socket.on(‘disconnect’, function () { });
        });

        Thanks for the quick reply though

        My next task is to get it to work with ‘Web Sharing’ on my mac.

        It works locally on my machine but I’m trying to allow any device on my router to be able to access the web page that connects to the socket.io server. It will go to the webpage and request ‘served static /socket.io.js’. But does not connect.

        Any thoughts?

        • http://www.codehenge.net Constantine Aaron Cois

          Hmm…are you running it through a local web server, or just trying to connect through some sort of share drive to the page? My first thought it to make sure the script address:

          is directed properly for dealing with a non-local resource.

  • Pwecker

    nice tutorial! thanks!

    but you will want to change line 37 of socket-io-test.html

    from ‘new io.Socket’ to ‘io.connect’

    • http://www.codehenge.net Constantine Aaron Cois

      Since the release of Socket.io 0.7, there are a number of outdated methods in this tutorial. I’m working on an updated one, which should be out very soon.

  • Pingback: Getting Started With node.js and socket.io (v0.7+) – Part 2 | Codehenge

  • Halcyon G3

    Hi, I tried running your code. But my client doesn’t connect to the server. The text that is displayed on the console is : socket.io started.What could be wrong?

  • Halcyon G3

    I get this on the console every time i run the .html page : served static content /socket.io.js

43 queries in 2.959 seconds