Real-Time Chat Application

Introduction

 
In this article, I will be guiding you to make a real-time chat application, with the help of Socket.IO and Node.js.
 
TalkVi is a real-time chat Application with Socket.IO. This is a node.js chat application, utilizing Express framework and Socket.IO.
 
Prerequisites
  1. Node.js should be installed on your local machine.
  2. Knowledge of - HTML,CSS,JavaScript and Node.js.
So, now we are ready to initiate our project.
 
Initially, we will open the terminal and create a directory which will be dedicated for our application. Now, we will navigate into that directory and run npm init. Then, we need to enter details about our application, which will be stored in 'Package.json' file. After this, we need to run below command,
  1. npm install --save express nodemon socket.io   
This command will install express,nodemon and socket.io modules which are the dependencies of our application. 
 
Our terminal should look like the following,
 
output 
  1. npm install --save-dev babel-cli babel-preset-env babel-preset-stage-0  
Above command will be installing babel-cli,babel-preset-env and babel-preset-stage-0 modules which are the dependencies of our project. 
 
Then, we will open the Package.json file in the text editor and add the following value corresponding to the key 'script'
  1. "start""nodemon ./app.js --exec babel-node -e js",   
So, the beginning of our Package.json file should look like the following,
  1. {    
  2.    "name""chat",    
  3.    "version""1.0.0",    
  4.    "description""",    
  5.    "main""index.js",    
  6.    "scripts": {    
  7.       "start""nodemon ./app.js --exec babel-node -e js",    
  8.       "test""echo \"Error: no test specified\" && exit 1"    
  9. },  
Then, we will be navigating to our project directory and we'll be creating a file named as .babelrc which will be opened in a text editor and the following text will be entered,
  1. {    
  2.    "presets": [    
  3.       "env",    
  4.       "stage-0"    
  5.    ]    
  6. }    
So, in this step, we have created the environment of our application.
 
Now, we will be creating a directory named public in our project directory. Inside this directory, there will be two files, namely 'index.html' and 'style.css'.
 
Our 'index.html' file will contain the following code,
  1. <!DOCTYPE html>    
  2. <html lang="en">    
  3.     
  4. <head>    
  5.     <title>ChatRoom</title>    
  6.     <meta charset="utf-8">    
  7.     <meta name="viewport" content="width=device-width, initial-scale=1">    
  8.     <link rel="stylesheet" href="style.css">    
  9.     <script>    
  10.         var name = prompt("Please enter your name");    
  11.     </script>    
  12. </head>    
  13.     
  14. <body>    
  15.     
  16.     <div id="intro">    
  17.         <h1>ChatRoom</h1>    
  18.     </div>    
  19.     
  20.     <ul id="messages"></ul>    
  21.     
  22.     <form action="">    
  23.         <input id="m" placeholder="Enter your message..." autocomplete="off" required /><button>Send</button>    
  24.     </form>    
  25.     
  26.     <script src="/socket.io/socket.io.js"></script>    
  27.     <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>    
  28.     <script>    
  29.     
  30.         var socket = io();    
  31.     
  32.         socket.emit('joining msg', name);    
  33.     
  34.         $('form').submit(function (e) {    
  35.             e.preventDefault();            // will prevent page reloading    
  36.             socket.emit('chat message', (name + ':  ' + $('#m').val()));    
  37.             $('#messages').append($('<li id="list">').text('You:  ' + $('#m').val()));    
  38.             $('#m').val('');    
  39.             return false;    
  40.         });    
  41.         socket.on('chat message'function (msg) {    
  42.             $('#messages').append($('<li>').text(msg));    
  43.         });    
  44.     
  45.     </script>    
  46. </body>    
  47.     
  48. </html>    
In the above code,
  1. <meta name="viewport" content="width=device-width, initial scale =1">     
This gives the browser instructions on how to control the page's dimensions and scaling of the project. 
  1. var name = prompt("Please enter your name");      
The above code will prompt the user to enter their name which will be stored in name variable.
  1. var socket = io();  
The above line in the code will try to connect to the host that serves the stage. Each socket also fires a special disconnect event when the user closes the page or refreshes it.This event will also be listened by the server.
 
When the user is connected to the server, socket.emit('joining msg',name); will be emitting a joining msg event along with the name of the user, which will be handled by the server. 
  1. <form action=””>    
  2.    <input id=”m” placeholder=”Enter your message…” autocomplete=”off” required /><button>Send</button>    
  3. </form>     
Above code will be creating a form for the user to enter messages. When this form is submitted, the following code will emit chat message event along with the name of the sender and the message to the server. The same message will also be displayed on the sender's browser. Then, the message input field will be emptied. 
 
 
Our project directory should look like the above. 
  1. $('form').submit(function(e) {  
  2.    e.preventDefault(); // will prevent page reloading  
  3.    socket.emit('chat message', (name + ': ' + $('#m').val()));  
  4.    $('#messages').append($('<li id="list">').text('You:'+ $('#m').val()));  
  5.    $('#m').val('');  
  6.    return false;  
  7. });  
The emitted chat message event when received by the server will be broadcast to all the other users as another emit event named chat message. This will be received and displayed by the browser with the help of the following code:
  1. socket.on('chat message'function(msg){  
  2.    $('#messages').append($('<li>').text(msg));  
  3. });   
Now that we have understood the function of out html file, we will be writing the CSS file so that our webpage looks good. Below is the code for Style.css,
  1. * {   
  2.     margin0;   
  3.     padding0;   
  4.     box-sizing: border-box;   
  5. }  
  6.    
  7.   #intro{  
  8.     background-color#008000;  
  9.     color#FFFFFF;  
  10.     height5%;   
  11.  }   
  12.   
  13.   
  14.  body {   
  15.     font20px;  
  16. }  
  17.   
  18.    
  19.    
  20.  form {   
  21.     background#000000;   
  22.     padding3px;   
  23.     positionfixed;   
  24.     bottom: 5px;   
  25.     width100%;   
  26.  }  
  27.    
  28.  form input {   
  29.     background-color#e6ffe6;  
  30.     border0;   
  31.     padding10px;   
  32.     width90%;   
  33.     margin-right0.5%;   
  34.  }  
  35.    
  36.  form button {   
  37.     width9%;   
  38.     background#00e600;  
  39.     bordernone;   
  40.     padding5px;   
  41.     font-size20px;   
  42.  }  
  43.    
  44.  #messages {   
  45.   
  46.     margin0;   
  47.     padding0;   
  48.       
  49.  }  
  50.    
  51.  #messages li {   
  52.     padding5px 10px;   
  53.  }  
  54.    
  55.  #messages li:nth-child(odd) {   
  56.     background#b3ffb3;   
  57.  }  
  58.   
  59.   
  60. #list{  
  61.     text-alignright;  
  62. }  
In the previous steps, we have completed writing codes for our front end. Now,we'll write codes for our backend in app.js file. 
  1. var express = require('express');  
  2. var http = require('http');  
  3.   
  4. var app = express();  
  5. var server = http.createServer(app);  
  6.   
  7. var io = require('socket.io')(server);  
  8. var path = require('path');  
  9.   
  10.   
  11. app.use(express.static(path.join(__dirname,'./public')));  
  12.   
  13. app.get('/', (req, res) => {  
  14.   res.sendFile(__dirname + '/public/index.html');  
  15. });  
  16.   
  17.   
  18. var name;  
  19.   
  20. io.on('connection', (socket) => {  
  21.   console.log('new user connected');  
  22.     
  23.   socket.on('joining msg', (username) => {  
  24.     name = username;  
  25.     io.emit('chat message', `---${name} joined the chat---`);  
  26.   });  
  27.     
  28.   socket.on('disconnect', () => {  
  29.     console.log('user disconnected');  
  30.     io.emit('chat message', `---${name} left the chat---`);  
  31.       
  32.   });  
  33.   socket.on('chat message', (msg) => {  
  34.     socket.broadcast.emit('chat message', msg);         //sending message to all except the sender  
  35.   });  
  36. });  
  37.   
  38. server.listen(3000, () => {  
  39.   console.log('Server listening on :3000');  
  40. });  
Our server application will send index.html file to the client. It will receive all the events emitted by the client and will properly handle them. It will also emit events which will be received by the client for proper functioning of our web application. 
 
Our coding is done, now we can start our server in the terminal using the command npm run start. The following message will be displayed. 
 
Server listening on :3000 
 
Now, we will open the browser and enter http://localhost:3000  in the address bar. The webpage will prompt us for our name. We can open this page in as many windows as we want. If we send a message from one window, it will be displayed in every window. So it is just like a real-time web-page opened in mutiple clients' browsers which are connected to a common server; i.e, localhost. Below is our webpage running over the browser,
 
 

Conclusion

 
In the above article, we explored about Socket.io, node.js and how the real-time communication takes place.We explored about the development mode setup and the environment setup for our project .