Getting Started with Socket.IO using NodeJS

In this blog post we will see how to start using socket.io with nodejs.

What is Socket.IO

As per the official website at http://socket.io/
” Socket.IO enables real-time bidirectional event-based communication.
It works on every platform, browser or device, focusing equally on reliability and speed. ”

What this means:
HTML5 introduced the WebSocket specification, which is a protocol to maintain an open line of communication between the client (browser) and server application. Client and server after establishing an initial handshake, can send messages back and forth to each other on real time.

To understand this even better, lets take an example of a php application where we need to display real time twitter feed on our website.

As per tradition programming,
On the browser (client site), we start a XHR (ajax) request and get information from the server on any new tweets. Once the ajax request is over, the connection closes and we need to create a new ajax request each time to get new information. So if we need our application to update tweets every minute; we would fire a new ajax request every minute, query for new tweet if any and display them on our browser. This is an inefficient process because
1. Creating a new XHR request every time take takes time. Time taken to establish connection every time causes a 100-500ms delay on each request.
2. We constantly poll the server every minute, there is no way for us knowing if new tweets have actually come up. Even then we need to create a new xhr request every minute even if now tweets are there. There is no way to send a message from the server to the client. This create unnecessary load on both client and server.
Both these flaws amount to a lot in big real time application. Hence the need for socket.io

Socket.IO is a layer which provides us with the tools to easily solve the above problem across browsers and also for older browser which don’t have websockets. Socket.IO falls back to websocket, htmlfile, xhr-polling, jsonp-polling, flashsocket on older browsers.

How to use

Socket.IO has two parts, client and server. So will see how to setup both

Server
To setup socket.io on server, create a new project and install socket.io using npm.

npm install socket.io

Create a new file node_server.js and write the following code

var io = require('socket.io')();
io.on('connection', function (socket) {
    console.log('connection');

    socket.emit('hello', {
        time: new Date()
    });
    socket.on('hello_reply', function (data) {
        console.log(data);
    });

});
io.listen(3000);

In the above code, as soon as connection is established with client, the server send a ‘hello’ event to client with current data.

Client Side Code
Create a new file index.html and include the socket.io.js client library from https://github.com/Automattic/socket.io-client in your file. Next write this code

<script src="socket.io.js"></script>
<script>
    var socket = io('http://127.0.0.1:3000');
    socket.on('connect', function () {
        console.log('connect event');
    });
    socket.on('hello', function (data) {
        console.log(data);
        socket.emit('hello_reply', {
            time: new Date()
        });
    });
    socket.on('disconnect', function () {
        console.log('disconnect event');
    });
</script>

In this we have written a code on ‘hello’ event, to reply back with ‘hello_reply’ event and current time as data packet.

Run the server on command line as

node node_server.js

and open the client file on your browser. Check console and command line to see bi-directional real time communication.

A Simple RealTime Chat Server

We will extend the above code, to create basic chat application.
Client Side

<script src="socket.io.js"></script>
<script src="http://code.jquery.com/jquery-2.1.1.min.js" type="text/javascript"></script>
<script>
    var socket = io('http://127.0.0.1:3000');
    socket.on('connect', function () {
        console.log('connect event');
    });
    socket.on('message_reply', function (data) {
        $('#log').append('<div>Recieve: ' + data.msg + '</div>')
    })
    socket.on('disconnect', function () {
        console.log('disconnect event');
    });
    $(document).ready(function () {
        $('#send').click(function () {
            var value = $('#msg').val();
            $('#msg').val('');
            socket.emit('message', {
                msg: value
            });
            $('#log').append('<div>Sent: ' + value + '</div>')
        });
    });
</script>

<input type="text" style="width: 200px" id="msg" />
<button type="button" id="send">Send</button>
<pre id="log">
    
</pre>

Server Side

var io = require('socket.io')();
var users = 0;
io.on('connection', function (socket) {
    console.log('connection');
    users++;
    socket.emit('message_reply', {
        msg: 'Total Users ' + users
    });
    socket.on('message', function (data) {
        console.log('message');
        socket.broadcast.emit('message_reply', data);
    });
    socket.on('disconnect', function () {
        users--;
        console.log('disconnect');
        socket.emit('message_reply', {
            msg: 'Total Users ' + users
        });
    });

});
io.listen(3000);

Above we have used a new function ‘socket.broadcast.emit’, which send message to all client except to the current socket (the current sender client). So person sending the message will not get the message back again.

I have written a more advance chat server implementation here
https://github.com/manishiitg/nodejs_socket_chat_demo
with feature to assign username based on socket connections.

There are various other modules/extension which can be coupled with socket.io for additional features: https://github.com/Automattic/socket.io/wiki/Modules-&-Extensions


Experiment
1. Extend the above chat server and save all chats to mongodb.
2. If a new user joins chat, he should see all previous chats of last 10minutes.