Simple Chat application with NodeJs and Socket.io

To building a chat application we need to implement long/short pooling with JavaScript or jQuery. We can’t say it real-time chat because the user has to wait until the poll response comes. Thanks to socket.io, which provides a bi-directional communication channel between a client and a server.

Requirements

Chat application structure

Let’s dive into the code to building the chat application with NodeJs. Create a directory with the name chatapp or whatever you like. Now change the directory to chatapp what should be your working directory. Now we have to install the dependencies packages that help us to build the chat application. First, install nodemon package. Nodemon automatically restarts the node application when a file change.

npm install --save-dev nodemon

Now install other dependencies with the following command.

npm install --save express body-parser socket.io

Once everything installed completely, we have to modify our package.json file, because we have installed nodemon locally so we have to add nodemon command to start our application.

{
  ...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon app/server.js"
  },
  ...
}

We have well structured this app, so we can extend it easily. So according to the app structure let’s create a config.js file in the root working directory. This file holds our global configurations, for now i have only added the port and the hostname because this is what we need for now.

const config = {
    port: 3000, 
    hostname: 'localhost'
};

module.exports = config;

Now create a file server.js at app/ directory and start to build the node app. Let’s add all the required dependencies.

const express = require('express');
const bodyParser = require('body-parser');
const socket_io = require('socket.io');

const frontRoute = require('./routes/frontend');
const config = require('./../config');

const app = express();

According to the above codes we have imported dependencies, configuration, and the route but we haven’t created the route yet. Let’s create the route at app/routes/ directory and name that frontend or whatever depends on you.

const path = require('path');
const express = require('express');

const router = express.Router();

router.get('/', (req, res, next) => {
    res.sendFile(path.join(__dirname, './../views', 'home.html'));
});

module.exports = router;

In the above code, I have created only one route and rendered the HTML through the sendFile() method. Create a home.html file at app/views/ directory.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Chat APP</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font: 13px Helvetica, Arial; }
        form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
        form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
        form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
        #messages { list-style-type: none; margin: 0; padding: 0; }
        #messages li { padding: 5px 10px; }
        #messages li:nth-child(odd) { background: #eee; }
    </style>
</head>
<body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
    <script>
        var socket = io();
    </script>
</body>
</html>

Come back to the app/server.js file and create a server to run the application.

app.use(bodyParser.urlencoded({extended: false}));
app.use(frontRoute);


var server = app.listen(config.port, config.hostname, () => {
    console.log(`app running on http://${config.hostname}:${config.port}`);
});

const io = socket_io.listen(server);

io.on('connection', (socket) => {
    console.log('Hello through socket.io');
});

Time to start your application and see if everything working fine.

npm start

Above command will look at our package.json file and execute the nodemon app/server.js command. Once everything runs without errors then open the browser and visit the following URL http://localhost:3000/ and you will see the output chatbox output and the terminal will output the “Hello through socket.io”

http://localhost:3000

Now we have to integrate the socket.io through client and server side. First, implement it from the client side, open the home.html file and start editing.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script>
        var socket = io();

        // Send to the Server
        $('form').submit(function(e) {
            e.preventDefault();

            var messageElement = $('#m'), 
                message = messageElement.val();

            if(message.length > 0) {
                socket.emit('chat_window', message);
                messageElement.val('');
            }

            return false;
        });

        // Display to the client
        socket.on('chat_window', function(message) {
            $('#messages').append($('<li>').text(message));
        });
    </script>

Above codes will send the text to the server through socket.emit(eventName, args); We have used the chat_window event that will listen by the socket.io on the server side through app/server.js file.

const io = socket_io.listen(server);

io.on('connection', (socket) => {
    socket.on('chat_window', (message) => {
        io.emit('chat_window', message);
    });
});

The socket.on(eventName, callback) only work once the chat_window event is triggered by the frontend. To communicate with the frontend, emitting another event. This event will receive the message sending from the server and display in the chat window.

This is what we have implemented and it is a very simple and basic chat application. Hope you guys enjoy the reading. You can check the complete and working code on the GitHub repository.

Posted by Jogesh Sharma

Jogesh Sharma is a web developer and blogger who loves all the things design and the technology, He love all the things having to do with PHP, WordPress, Joomla, Magento, Durpal, Codeigniter, jQuery, HTML5 etc. He is the author of this blog.