CodeProject
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
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
<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) {
var serverMsg = document.getElementById("serverMsg");
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.
- A
div
element to show the exchange of messages between two/more people. - A message box, and a send button to send the message to others.
- 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.
<html>
<head>
<title>Chat application with Node and Sockets</title>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
</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.
var name,
socket = io.connect("http://localhost:1234");
$(function () {
name = window.prompt("enter your name");
if (name == null) {
$("body").html(" please refresh the page and try again ");
}
$("#send").click(function () {
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.
<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:
io.sockets.on('connection', function (socket) {
socket.on("clientMsg", function (data) {
socket.emit("serverMsg", data);
socket.broadcast.emit("serverMsg", data);
});
});
Notice that there are two emit statements within the above connection event.
socket.emit("serverMsg", data);
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.
$("#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.
socket.on("sender", function (data) {
socket.emit("sender", data);
socket.broadcast.emit("sender", data);
});
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.
<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:
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:
<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 () {
name = window.prompt("enter your name");
if (name == null) {
$("body").html(" please refresh the page and try again ");
}
$("#send").click(function () {
socket.emit("clientMsg", {
"name": name,
"msg": $("#msg").val()
});
});
socket.on("serverMsg", function (data) {
$("#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:
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) {
socket.on("clientMsg", function (data) {
socket.emit("serverMsg", data);
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!