Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / Node.js

Simple Chat Application using NodeJS and Socket.IO

4.85/5 (12 votes)
24 May 2014CPOL6 min read 59.2K  
This is a simple chat application using NodeJS and Socket.IO

Before we start creating a chat application with NodeJS, I'll just give you a brief idea of what NodeJS and Socket.IO is and what it does.

What is NodeJS ?

NodeJS is a platform built for fast, scalable network applications. It is also used for creating real-time applications that interact with data related tasks.

You can download NodeJS from here. Choose the type of the Operating System and download and install NodeJS.

What is Socket.IO ?

Socket.IO aims to make realtime apps possible in every browser and mobile device, blurring the differences between the different transport mechanisms. It's care-free realtime 100% in JavaScript.

After installing NodeJS setup, choose a folder in which you want to create the application. Once you're done with choosing the folder of your choice, go ahead and download Socket.IO from github. Extract the downloaded sockets.io to the folder that you're using for creating the app.

If you're a Windows user, just open the cmd, and navigate to the ChatApp folder. Type npm install socket.io, this will add a node_modules folder created within the ChatApp folder which also contains socket.io folder.

That's it and you're done with setup of NodeJS. All you've to do now is just give it a try to check if it is working properly. Let's code some JavaScript on server end.

server.js

JavaScript
var app = require('http').createServer(handler),
    io = require('socket.io').listen(app),
    fs = require('fs')

 app.listen(80);

function handler(req, res) {
    fs.readFile(__dirname + '/index.html',
        function (err, data) {
            if (err) {
                res.writeHead(500);
                return res.end('Error loading index.html');
            }

            res.writeHead(200);
            res.end(data);
        });
}

io.sockets.on('connection', function (socket) {
    socket.emit('news', {
        hello: 'world'
    });
    socket.on('my other event', function (data) {
        console.log(data);
    });
}); 

The above code is just copied from socket.io web site. First of all, we create a http server with the handler as a callback function. The server is made to listen to port 80. If you've a server which is already consuming the port, just change it. The handler callback function accepts a request and response arguments, which is a basic thing that every server does. The interesting thing about Socket.IO is that the html files are to be served by the server itself as you can see in the handler function, which loads index.html file to the file stream and writes everything to the response.

Socket.IO is built on top of Web Socket API, to support all the major browser including IE 5.5+ and you can find more information regarding browser support at http://socket.io/#browser-support.

What Socket.IO will do is it will detect if the connection will be established through Web Socket, AJAX long polling, Flash etc and acts accordingly. When a connection request is made by the client, a socket is created and the message is sent to the client over the socket. We can probably guess the message from the above code. Its a property with the name as hello, which has a message 'world'. Notice that there is also an event binded to the socket (my other event). When the 'my other event' is called by passing data, it just logs to the browser console.

Now let's add some html to it, to make it really functional.

index.html

JavaScript
<html>

<head>
    <title>Getting started with Sockets</title>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io.connect("http://localhost:1234");

        socket.on("news", function (data) {
            //grab the element for which you've to add the message from server
            var serverMsg = document.getElementById("serverMsg");
            //add the message received from server to the element
            serverMsg.innerHTML += data.hello;
        });
    </script>
</head>

<body>
    <div id="serverMsg">Waiting for the message from server:</div>
</body>

</html>        

That's it from the HTML side. All you've to do is just go to the folder where you've saved this index.html file and the server.js file from command prompt.
Type node server.js and press enter.
You should see a message in the command prompt as

info - socket.io started

Now your Node server is started. Open any browser and access the localhost with port number (Example: http://localhost:1234/).

That's great! We're done with the basic message receiving/sending task using NodeJS. Now let's move on and create a simple chat app, which is just sending the message from one end and receiving the message at the other end and vice versa.

Let's evaluate the things/requirements needed to create a simple chat application.

  1. A div element to show the exchange of messages between two/more people.
  2. A message box, and a send button to send the message to others.
  3. And finally a little bit of coding to do this process.

Let's get started. Now, I'll just setup HTML for this chat app. Here is the HTML for it.

JavaScript
<html>
<head>
    <title>Chat application with Node and Sockets</title>
    <script src="/socket.io/socket.io.js"></script>
    <script type="text/javascript">
        //javascript goes here...
    </script>
</head>

<body>
    <!--Message box: To show the sent/received messages-->
    <div id="msgBox" style="height: 200px; width: 400px; border: 1px solid blue;">

    </div>
    <!--Textbox: to enter the message text-->
    <input type="text" id="msg" style="width:300px" />
    <!--Send: A button to send the message to others-->
    <input type="submit" id="send" value="send" />
</body>
</html>        

Now let's call/save this as index.html. It's time to write some JavaScript to send the message to the server.

JavaScript
var name,
    socket = io.connect("http://localhost:1234");

$(function () {

    //as the user to enter their nick name or name.
    name = window.prompt("enter your name");

    //If the name is not given, ask the user to enter once again
    if (name == null) {
        $("body").html(" please refresh the page and try again ");
    }

    //When send button is clicked on, send the message to server
    $("#send").click(function () {

        //send to the server with person name and message
        socket.emit("clientMsg", {
            "name": name,
            "msg": $("#msg").val()
        });
    });
});

This JavaScript has to placed within the script tags of index.html. I've used jQuery functions in the above code. Please do not forget to add the following line before to the above script.

JavaScript
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>

That's all the code from client side. Let's switch on to server side code. Let's call the code at server as chatapp.js. For chatapp.js, we've to write the initial setup connection with socket and an event wireup when the connection is made. Copy the code that we've used for hello world program, and paste it into the chatapp.js. Replace the code in "connection" event with the following:

JavaScript
io.sockets.on('connection', function (socket) {

    //when receiving the data from the server, push the same message to client.
    socket.on("clientMsg", function (data) {

        //send the data to the current client requested/sent.
        socket.emit("serverMsg", data);

        //send the data to all the clients who are accessing the same site(localhost)
        socket.broadcast.emit("serverMsg", data);
    });
});

Notice that there are two emit statements within the above connection event.

  1. socket.emit("serverMsg", data);
  2. socket.broadcast.emit("serverMsg", data);

The first statement only emits the message received from the client to its respective client. The second statement emits the message sent from one client to all the other clients who are using the same host.

To understand better, open two browsers side by side and run on the same host. Comment line 1 and line 2 alternatively to observe the difference. That's it and you're done with a simple chat app that can receive and send message.

To make it feel more user friendly, we can add the status of the person who is typing. All we've to do is just to wireup and event handler when a key is pressed on the messagebox.

JavaScript
$("#msg").on("keyup", function (event) {
    socket.emit("sender", {
        name: name
    });
}); 

So, when any user types something in the textbox, then all the other users on the same host should receive a message on to their browser that user is typing.

The above code is to be appended in the dom ready of jQuery, i.e., anywhere within $(function(){... is needed. Now, when the user sends the username to the server saying that the person is typing, we'll have to broadcast the user who is typing to all the other users. This is just similar to what we've done previously to send the message to all the other users.

JavaScript
socket.on("sender", function (data) {
    socket.emit("sender", data);
    socket.broadcast.emit("sender", data); //Broadcast the user typing to 
                                           //all the other users over the network
});

So, after broadcasting the message over the network, we've to display the user who is typing in the network. This can be done by simply adding a div element to the body tag.

JavaScript
<div id="status"></div>

Also the following script is to be added to the same DOM ready in jQuery in order to add the status of the person who is typing:

JavaScript
socket.on("sender", function (data) {
    $("#status").html(data.name + " is typing");
    setTimeout(function () {
        $("#status").html('');
    }, 3000);
}); 

So, upon receiving the data from the server each time a user presses any key, the status is logged on to the div. If the user leaves the text field idle for 3 seconds, then we will have to clear the div to make sure that the same user is not typing now. The setTimeout function is used for this purpose. It will be fired after 3 seconds and the code inside the setTimeout function is executed.

I understand that the code written above is scattered over the areas. I'll just merge all the code for you . Here is how the index.html file looks like after all additions:

JavaScript
<html>

<head>
    <title>Chat application with Node and Sockets</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    <script>
        var name,
            socket = io.connect("http://localhost:1234");
        $(function () {
            //as the user to enter their nick name or name.
            name = window.prompt("enter your name");
            //If the name is not given, ask the user to enter once again
            if (name == null) {
                $("body").html(" please refresh the page and try again ");
            }
            //When send button is clicked on, send the message to server
            $("#send").click(function () {
                //send to the server with person name and message
                socket.emit("clientMsg", {
                    "name": name,
                    "msg": $("#msg").val()
                });
            });

            //After sending message to the server, we'll have to wire up the event for it.
            //We can do the following. Upon receiving the message print it to the message box
            //that we've created in our html
            socket.on("serverMsg", function (data) {
                //Append the message from the server to the message box
                $("#msgBox").append("<strong>" + data.name + 
                "</strong>: " + data.msg + "<br/>");
            });

            $("#msg").on("keyup", function (event) {
                socket.emit("sender", {
                    name: name
                });
            });

            socket.on("sender", function (data) {
                $("#status").html(data.name + " is typing");
                setTimeout(function () {
                    $("#status").html('');
                }, 3000);
            });
        });
    </script>
</head>

<body>
    <!--Message box: To show the sent/received messages-->
    <div id="msgBox" style="height: 200px; width: 400px; border: 1px solid blue;">

    </div>
    <!--Textbox: to enter the message text-->
    <input type="text" id="msg" style="width:300px" />
    <!--Send: A button to send the message to others-->
    <input type="submit" id="send" value="send" />
    <br/>
    <div id="status"></div>
</body>

</html>

and chatapp.js:

JavaScript
var app = require("http").createServer(handler),
    io = require("socket.io").listen(app),
    fs = require("fs");

app.listen(1234);

function handler(req, res) {
    fs.readFile(__dirname + '/index.html',
        function (err, data) {
            if (err) {
                res.writeHead(500);
                return res.end('Error loading index.html');
            }
            res.writeHead(200);
            res.end(data);
        });
}

io.sockets.on('connection', function (socket) {
    //when receiving the data from the server, push the same message to client.
    socket.on("clientMsg", function (data) {
        //send the data to the current client requested/sent.
        socket.emit("serverMsg", data);
        //send the data to all the clients who are accessing the same site(localhost)
        socket.broadcast.emit("serverMsg", data);
    });

    socket.on("sender", function (data) {
        socket.emit("sender", data);
        socket.broadcast.emit("sender", data);
    });
});   

That's it! And you're done with basic message sending/receiving example with NodeJS and Socket.IO.

Leave a comment if you're struck at any point while creating the chat application.

Thanks for reading!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)