Deploy Node JS app on Heroku

When it comes to deploy Node JS app, Heroku is by far the most feasible choice for beginners and startups. In this tutorial, we are going to teach you how you can deploy your Node JS application on Heroku and make it accessible from everywhere.

It is very common when we start building our Node JS apps, we mostly work on our localhost for faster testing. But when there is a time to make it live or connect it with your android or iOS application, you definitely need to publish it on some hosting provider. Heroku in this regard will help us to publish our Node JS app on their server.

Let’s get started

We are going to create a simple “Hello world” app in Node JS and publish it on Heroku.

First create a new folder where we will place all our Node JS files. If you are already working on some Node JS project, then you can use your existing folder too. Create a file named “server.js”, this will be our main server file. Open the command prompt in your project and initialize NPM in it, make sure you have Node JS installed in your computer. You can download Node JS from here:

cd "your_project_root_folder"
npm init

Install modules

Install express and Http modules in your project, they will be used to start the server at a specific port. After installation, we are going to start the server using nodemon command. If you do not have nodemon, you can install it by running “npm i nodemon” in your terminal. Run the following command in your terminal to install express & Http modules and start the server:

npm install express http
nodemon server.js

Now we will create instances of express and Http modules and start the server at port 3000. Specifying the port will work on the localhost, but when we deploy any app on Heroku, Heroku automatically assigns some port number from itself and save that port number in the “process” object’s “env” object. So we will add an OR operator to set port number if it is being received from Heroku, otherwise (if in localhost) start at 3000. Paste the following code in your server.js file:

var express = require("express");
var app = express();
var http = require("http").createServer(app);

http.listen(process.env.PORT || 3000, function () {
	app.get("/", function (request, result) {
		result.send("Hello world !");
	});
});

If you test the app now at URL “http://localhost:3000/” you will see a “Hello world !” message. Now we need to deploy on Heroku, goto Heroku and login or signup if you have’nt already created an account.

Deploy Node JS on Heroku

Now download and install the Heroku CLI. Run the following command in your terminal to login, it will open the browser, just hit “Login” in opened web page. Also make sure that you have Git installed too, you can download it from here:

heroku login

// Initialize a Git repository
git init

// Point remote address towards your Heroku app
heroku git:remote -a your-app-name

// Add all files in Git
git add .

// Commit all files
git commit -am "Initial commit"

// Deploy all files on Heroku
git push heroku master

After the final command, you will see a link of your app which you can use to run directly in the browser. Moreover, in your Heroku dashboard, you can click on “Open app” button and it will take you to your app’s home page.

Learn how to deploy Node JS app with Mongo DB and Vue JS from here.

Upload file along with other input fields – Node JS

So we are going to teach you how you can upload the file from HTML form along with other input fields in Node JS. We will be using NPM’s formidable, fs (file system) and EJS modules. We will create an input type file to select a file from computer and input type text, the file will be store in server with the name I enter in text box.

Let’s get started

Open command prompt in your project’s root folder and run the following command to install necessary modules:

npm install express http formidable fs ejs
  • Express and HTTP will be used to start the server
  • formidable will be used to handle the input file
  • fs (file system) will be used to save the file
  • EJS will be used to render the HTML page

Now create a file named index.js and paste the following code in it:

var express = require("express");
var app = express();
var http = require("http").createServer(app);
var formidable = require("formidable");
var fs = require("fs");

app.set("view engine", "ejs");

http.listen(4000, function () {
	app.get("/", function (request, result) {
		result.render("index");
	});
});

It will start the server at port number 4000 and creates a default route which when access will render the index.ejs page. We will create that file in a moment. We are setting the default template engine to EJS, don’t worry if you are using any other engine, the core login will remain the same.

Start the server

To start the server, simply run the following command in your command prompt which should be opened in your project’s root folder:

npm install -g nodemon
nodemon index.js

Now you can access your server by running the following URL in your browser:
http://localhost:4000/

Display input type file

Now create a folder in your project named “views”. Your all HTML files should be placed inside this folder and all files must end with an extension .ejs. Create a file named index.ejs inside this views folder. The name of the file must be the same as in render function above, along with .ejs extension at the end. Paste the following code in that file. It will create a form with an input field to select a file and an input field to enter text. We will save the uploaded file with the name entered in text box.

<form method="POST" action="/upload" enctype="multipart/form-data">
	<input type="file" name="file">
	<input type="text" name="fileName" placeholder="File name">

	<input type="submit">
</form>

Save file on server

Make sure the method is POST and encoding type must be attached, otherwise, the file will not be sent. Action attribute will specify the route where data should be sent. So paste the following code in your index.js file right below the “/” route:

app.post("/upload", function (request, result) {
	var formData = new formidable.IncomingForm();
	formData.parse(request, function (error, fields, files) {
		var extension = files.file.name.substr(files.file.name.lastIndexOf("."));
		var newPath = "uploads/" + fields.fileName + extension;
		fs.rename(files.file.path, newPath, function (errorRename) {
			result.send("File saved = " + newPath);
		});
	});
});

Now you just need to create a folder named “uploads” and when you select the file. Enter the name, the file will be saved with the name you enter in the text field. That’s how you can upload a file on Node JS server.

[wpdm_package id=’245′]

Show realtime website users counter – Node JS

In this article, we are going to show you how you can get realtime website users counter using Node JS. Paste the following code in page where you want to display the counter:

HTML

<div class="row">
	<div id="countdown">
		<div id='tiles'>
			<span>0</span>
			<span>0</span>
			<span>0</span>
			<span>0</span>
		</div>

		<div class="labels">
			<li>Registered users</li>
		</div>
	</div>
</div>

CSS

#countdown{
    width: 465px;
    height: 170px;
    text-align: center;
    background: #222;
    background-image: -webkit-linear-gradient(top, #222, #333, #333, #222); 
    background-image:    -moz-linear-gradient(top, #222, #333, #333, #222);
    background-image:     -ms-linear-gradient(top, #222, #333, #333, #222);
    background-image:      -o-linear-gradient(top, #222, #333, #333, #222);
    border: 1px solid #111;
    border-radius: 5px;
    box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.6);
    margin: auto;
    padding: 24px 0;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

#countdown:before{
    content:"";
    width: 8px;
    height: 65px;
    background: #444;
    background-image: -webkit-linear-gradient(top, #555, #444, #444, #555); 
    background-image:    -moz-linear-gradient(top, #555, #444, #444, #555);
    background-image:     -ms-linear-gradient(top, #555, #444, #444, #555);
    background-image:      -o-linear-gradient(top, #555, #444, #444, #555);
    border: 1px solid #111;
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
    display: block;
    position: absolute;
    top: 48px; left: -10px;
}

#countdown:after{
    content:"";
    width: 8px;
    height: 65px;
    background: #444;
    background-image: -webkit-linear-gradient(top, #555, #444, #444, #555); 
    background-image:    -moz-linear-gradient(top, #555, #444, #444, #555);
    background-image:     -ms-linear-gradient(top, #555, #444, #444, #555);
    background-image:      -o-linear-gradient(top, #555, #444, #444, #555);
    border: 1px solid #111;
    border-top-right-radius: 6px;
    border-bottom-right-radius: 6px;
    display: block;
    position: absolute;
    top: 48px; right: -10px;
}

#countdown #tiles{
    position: relative;
    z-index: 1;
}

#countdown #tiles > span{
    width: 92px;
    max-width: 92px;
    font: bold 48px 'Droid Sans', Arial, sans-serif;
    text-align: center;
    color: #111;
    background-color: #ddd;
    background-image: -webkit-linear-gradient(top, #bbb, #eee); 
    background-image:    -moz-linear-gradient(top, #bbb, #eee);
    background-image:     -ms-linear-gradient(top, #bbb, #eee);
    background-image:      -o-linear-gradient(top, #bbb, #eee);
    border-top: 1px solid #fff;
    border-radius: 3px;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.7);
    margin: 0 7px;
    padding: 18px 0;
    display: inline-block;
    position: relative;
}

#countdown #tiles > span:before{
    content:"";
    width: 100%;
    height: 13px;
    background: #111;
    display: block;
    padding: 0 3px;
    position: absolute;
    top: 41%; left: -3px;
    z-index: -1;
}

#countdown #tiles > span:after{
    content:"";
    width: 100%;
    height: 1px;
    background: #eee;
    border-top: 1px solid #333;
    display: block;
    position: absolute;
    top: 48%; left: 0;
}

#countdown .labels{
    width: 100%;
    height: 25px;
    text-align: center;
    position: absolute;
    bottom: 8px;
}

#countdown .labels li{
    /*width: 102px;*/
    font: bold 15px 'Droid Sans', Arial, sans-serif;
    color: #f47321;
    text-shadow: 1px 1px 0px #000;
    text-align: center;
    text-transform: uppercase;
    display: inline-block;
}

Display currently registered users

Paste the following code before the counter is displayed:

<?php
	$conn = mysqli_connect("localhost:8889", "root", "root", "classicmodels");
	$result = mysqli_query($conn, "SELECT COUNT(*) AS total_users FROM users");
	$row = mysqli_fetch_object($result);
	$total_users = $row->total_users;
	$total_users = substr("0000" . $total_users, -4);
?>

This will return the number of users in 4 digit format. For example, if your website has 275 users then substr(“0000” . $total_users, -4):

  • “0000” will print 4 zeroes.
  • $total_users will append 275, thus makes 0000275.
  • -4 will pick the last 4 characters, thus becomes 0275.

We need to display each character in 1 block, so we will loop through length of this digit and display single character in each iteration.

<?php for ($a = 0; $a < strlen($total_users); $a++) { ?>
	<span><?php echo $total_users[$a]; ?></span>
<?php } ?>

Setup Node JS

Download and install Node JS from here. After installation, create a new folder for Node JS and create a new file named “index.js”. Open command prompt in this folder and run the following command:

npm init

This will initialize the directory. Then you need to install 3 modules for this, you can install all 3 of them from single command:

npm install express http socket.io

When all above modules installs, open your index.js file and paste the following code in it:

var express = require("express");
var app = express();
var http = require("http").createServer(app);
var socketIO = require("socket.io")(http);

http.listen(3000, function () {
	socketIO.on("connection", function (socket) {
		socket.on("new_user", function () {
			socket.broadcast.emit("new_user");
		});
	});
});

And run the command in your command prompt:

node index.js

This will start the server and keep listen for incoming events for “new_user” event. As soon that event is received, it broadcast that event to all other connected clients. Broadcast means to send the event to all users except the one who sends it.

Send event when new user gets registered

So the server is listening for incoming events and sending to all other connected clients. Now we need to send event whenever new user gets registered. On registration form, attach an onsubmit event and call a function to send event to server. Make sure the function must returns true otherwise your action attribute will not work.

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

<form action="your_action_page" onsubmit="return sendEvent();" method="POST">

JS

function sendEvent() {
	var socketIO = io("http://localhost:3000/");
	socketIO.emit("new_user");
	return true;
}

Receive event on counter page

So an event is sent from registration page to server, and sends it to all other connected clients. But there isn’t any client to receive it yet, so we will be listening to this event on our page where we want to display the counter. In this case, we are displaying counter on home page.

When the event is received we will increment the current users number and display it in 4 digit format, like we did for PHP. In order to increment the current number, we first must have the old number, so we have created an hidden field for it.

<input type="hidden" id="total_users" value="<?php echo $row->total_users; ?>">

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

JS

var socketIO = io("http://localhost:3000/");
socketIO.on("new_user", function () {
	var total_users = document.getElementById("total_users").value;
	total_users++;

	var totalUsers_Str = total_users + "";
	totalUsers_Str = totalUsers_Str.padStart(4, "0");

	var html = "";
	for (var a = 0; a < totalUsers_Str.length; a++) {
		html += "<span>" + totalUsers_Str[a] + "</span>";
	}

	document.getElementById("tiles").innerHTML = html;
	document.getElementById("total_users").value = total_users;
});

This tutorial is created in core PHP and vanilla Javascript, but may be you were working in Laravel or in any other framework, so you might face minor problems to integrate this in your scenario. If you face any issue, you can always contact us and we will help you out.

That’s how you can show realtime website users counter in your website using PHP and Node JS.

[wpdm_package id=’233′]

Get realtime notification from contact us form to admin panel – Node JS

You can receive realtime notification on your admin panel for your website’s contact us form using simple Node JS script. You can download Node JS from here and install it in your system.

Above screenshot is the demo of what we are going to create. On left we have contact us page from where users can send a message to admin. And on right we have admin panel where admin will be able to view messages without refreshing the page.

Sending message from contact us form

Your typical contact us form might have the following fields:

<form action="#">
	<input type="text" id="name">
	<input type="text" id="email">
	<input type="text" id="subject">
	<textarea id="message"></textarea>

	<input type="button" onclick="sendMessage()" value="Send Message">
</form>

<script>
	function sendMessage() {
		//
	}
</script>

You might also have different fields too but it does not matter. The most important thing is, your form should:

  1. Have ID attribute to all fields.
  2. For submit button, input type must be “button”, not “submit”.
  3. The button needs to have an “onclick” listener.
  4. A function with same name must be created inside script tag.

Now we will be sending an event from socket. You can all an AJAX function too if you want to perform other actions too. First you need to include socket-io.js in your project, you can use the below CDN link to do that. Paste the following code anywhere in your contact us page:

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

Then you have to create an instance for IO object and in sendMessage() function, you have to emit an event using this IO object. Sending an event is commonly refer to as “Emitting an event”.

var socket = io("http://192.168.43.64:3000");

function sendMessage() {
	socket.emit("messageSent", {
		"name": document.getElementById("name").value,
		"email": document.getElementById("email").value,
		"subject": document.getElementById("subject").value,
		"message": document.getElementById("message").value
	});

	// Call an AJAX for further actions you want to perform (like saving in database etc.)
}

io constructor will receive an IP address and port number where Node JS server will be running. You can get your local IP address from terminal by running the command: ifconfig and search for line having “ipv4”, your local IP address will be right next to “ipv4”. You can run your Node JS project on any port number other than 8080 (default for apache) and 3306 (default for MySQL). It will return a socket object which can be used to send an receive events from server. To send an event, we will calling a function named emit(eventName, data), it has 2 argument:

  1. First argument is the name of event that needs to be send.
  2. Second will be the data that needs to be send with this event. Here you can place all your contact us fields using their IDs.

Node JS server

Now we need a medium which will listen to this event and respond accordingly. So we assume that you have installed Node JS in your computer.

  1. Create a folder named “nodejs-server” anywhere in your system. I am creating it at desktop.
  2. Open terminal in that folder (shift + right click) and run the following command one at a time:
npm init

This will initialize the folder as Node JS project.

npm install express

This will install the express module used to create a server.

npm install http

This module will be used to start the server at specific port (3000 in our case).

npm install socket.io

This module will be used to listen events from client, and emit events to clients.

server.js

Create a file named “server.js” in newly created folder (“nodejs-server” in our case) and paste the following code in it:

var express = require("express");
var app = express();

var http = require("http").createServer(app);
var io = require("socket.io")(http);

http.listen(3000, function () {
    console.log("Server connected");

    io.on("connection", function (socket) {
        console.log("User " + socket.id);

        socket.on("messageSent", function (message) {
            socket.broadcast.emit("messageSent", message);
        });
    });
});

Remeber this file is a Javascript file so it does not need a <script> tag in it. We will explain each later in a moment. To start the server, run the following command in terminal or command prompt in that folder:

node server.js
  • First we created an instance of express and initialize it, saved it in a variable named “app”.
  • Similarly, we created “http” and “socket.io” instances. Http is created from express module. And socket.io is created from Http.
  • Then we start the server using listen function. First parameter will be port number and second will be a call back function that will be called when the server started running.
io.on("connection", function (socket) {
  • This function will be called when a new client connected with Node JS server. Client is connected by calling io() function from web page.
  • Then we are listening to “messageSent” event from client. That function will be called when client emits that event (in our case, from contact us form).
  • Then we are sending this event to all other connected clients. Broadcast will send the event to all connected clients other than the one who sends it.

Receive realtime notification on admin panel

So we are emitting event from contact us form and broadcasting it to all other connected clients from Node JS app. But who are the “other clients” ?
The one who will be listening to that event. So we are going to make admins to listen to that event. Paste the following code in all files on admin panel where you want to receive realtime notifications. Or you can paste them in admin template’s header or footer file as that will be included in each file.

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/notify/0.4.2/notify.js"></script>

<script>
	var socket = io("http://192.168.43.64:3000");

	socket.on("messageSent", function (message) {
		$.notify("New Message\n" + message.message + "\n\nFrom: " + message.name, {
			autoHide: false,
			className: "success"
		});
	});
</script>

First we added socket IO and created an instance like we did for contact us page. We are using https://notifyjs.jpillora.com/ library to display a simple alert realtime notification but once you have attach an event listener, you can display the realtime notification as per you need. jQuery is also added for notify.js, otherwise you do not need jQuery for socket IO.

That’s how you can receive realtime notification from your contact us form in your admin panel. Learn how to create a realtime customer support chat widget from here.

Private user to user chat in Node JS & MySQL

Private chat does not mean that there is not any server between sender and receiver. There will always be a server in the middle of you and the person you are chatting with. That does not mean that they are spying on your data. It means that they are providing you a medium where you can send and receive messages from others.

It is cost effective since you do not have to pay or worry about the server. A realtime server could take a lot of physical space. It also needs to be air-cooled 24 hours a day, 7 days a week. Also, you need to maintain those servers time-to-time from any failure. You also have to consider all the possible attacks from hackers.

Node JS

Node JS is a Javascript based server that provides realtime event notifications. It is the first thing that came in the mind of developers when they have to develop a private chat. Or even group chat. When you use Facebook, you do not need to refresh the page to see new likes or comments. When you receive a new notification, it will automatically be displayed at the corner left of screen.

Here’s how it works, when you send a message an event will be sent to the server to notify that user. Server will receive that event and send the same event to that specific user. Every user will be listening from server for incoming events. Now, whenever that event received from server a notification will be displayed. You can download and install Node JS from it’s official site.

Setup the project

Create a new folder anywhere in your computer (Node JS can run in any directory). Open that folder in terminal by running command:

cd "path_to_folder"

If you have downloaded and installed Node JS in your computer, you can run the following command to initialize the project:

npm init

You will be asked a series of questions like author, name, description, version etc. You can press enter for all these fields. Then you need to install Express, Http and Socket IO modules. Run the following commands one by one:

npm install express http socket.io
npm install -g nodemon

You do not need to run the last command if you have already installed the “nodemon” module, it helps to keep the server running and the server will restart itself if any change has been made in the server file. The above commands will install the necessary modules to start the server. Next, you are going to need is to download jQuery and Socket IO JS. You can download jQuery from here and Socket IO from here.

Create a new folder named “JS” and paste these files there. Then create a file at the root of your project folder and named it “server.js”, this will be served as your server. Open that file and paste the following code into it:

server.js

// creating express instance
var express = require("express");
var app = express();

// creating http instance
var http = require("http").createServer(app);

// creating socket io instance
var io = require("socket.io")(http);

// start the server
http.listen(3000, function () {
	console.log("Server started");
});

To start the server, open back the terminal and run the following command:

nodemon server.js

This will keep the server running and whenever you make any changes in “server.js” it will automatically restarts itself.

Display connected users

For private chat, the user must select the person he wants to chat with. To do that, create a new file, which will served as a client, named “index.php”. Paste the following code in it:

index.php

<!-- include jquery and socket IO -->
<script src="js/jquery.js"></script>
<script src="js/socket.io.js"></script>

<script>
  // creating io instance
  var io = io("http://localhost:3000");

  var receiver = "";
  var sender = "";

</script>

server.js

io.on("connection", function (socket) {
	console.log("User connected", socket.id);
});

The client will connect with the server and the server will keep listening from the client. As soon as one client connected IO “connection” event will be fired and his socket will be created with a unique ID. Now create a form to enter username and that name will be sent along with each user’s message.

index.php

<form onsubmit="return enterName();">
  <input id="name" placeholder="Enter name">
  <input type="submit">
</form>

<ul id="users"></ul>
	
<script>
	function enterName() {
	    // get username
	    var name = document.getElementById("name").value;

	    // send it to server
	    io.emit("user_connected", name);

	    // save my name in global variable
	    sender = name;

	    // prevent the form from submitting
	    return false;
	}

	// listen from server
	io.on("user_connected", function (username) {
		var html = "";
		html += "<li><button onclick='onUserSelected(this.innerHTML);'>" + username + "</button></li>";

		document.getElementById("users").innerHTML += html;
	});

	function onUserSelected(username) {
	    // save selected user in global variable
	    receiver = username;
	  }
</script>

server.js

var users = [];

io.on("connection", function (socket) {
	console.log("User connected", socket.id);

	// attach incoming listener for new user
	socket.on("user_connected", function (username) {
		// save in array
		users[username] = socket.id;

		// socket ID will be used to send message to individual person

		// notify all connected clients
		io.emit("user_connected", username);
	});
});

Now a form will be displayed where you can enter your name. When form submits, a function named “enterName()” will be called which stored your entered name in a global variable and send an event to the server with that name. The server will listen that event from the client, a new array will be created which holds socket ID of each user identified by his username and send the same event to all connected clients.

Same event is also attached on client side which when called will create a button with username and append it into a list. When that button is pressed, then a function will be called which stores that person’s name in another global variable. These global variables will be used when sending the message.

Send private chat message to selected user

Select a person from the list and now if you open your browser console, you will be able to enter variable “receiver” and it will print out the selected username. Similarly, you can enter “sender” and it will print your name. To send a message you have to follow almost same steps as for displaying connected users.

Create a form, on submit send an event to server. Server will get that person’s socket ID from his username and send an event to that person only. Every user will be listening for that event, whenever that event is received, display the incoming message in a list. After sending message you have to append in the list too so you can see your own messages too.

index.php

<form onsubmit="return sendMessage();">
  <input id="message" placeholder="Enter message">
  <input type="submit">
</form>

<ul id="messages"></ul>
	
<script>
	function sendMessage() {
		// get message
		var message = document.getElementById("message").value;

		// send message to server
		io.emit("send_message", {
		  sender: sender,
		  receiver: receiver,
		  message: message
		});

		// append your own message
		var html = "";
		html += "<li>You said: " + message + "</li>";

		document.getElementById("messages").innerHTML += html;

		// prevent form from submitting
		return false;
	}

	// listen from server
	io.on("new_message", function (data) {
		var html = "";
		html += "<li>" + data.sender + " says: " + data.message + "</li>";

		document.getElementById("messages").innerHTML += html;
	});
</script>

server.js

// listen from client inside IO "connection" event
socket.on("send_message", function (data) {
	// send event to receiver
	var socketId = users[data.receiver];

	io.to(socketId).emit("new_message", data);
});

Open 2 browsers and choose different names for both browsers. Send a message from 1 browser to another and you will see new message on both browsers. You can see that you can chat with each other but when you refresh the page, all previous messages will be removed. That’s because we are not storing any message anywhere, they are just sent and received from one client to another.

When it comes to saving data, you have multiple choices. You can save data in relational database like MySQL, you can save in no-relational database like Mongo DB or you can save in files too in XML or JSON format.

Save messages in MySQL

Saving data in relational database is most easy and reliable among all mentioned above. So create a new database in your phpMyAdmin, you can select any name but for simplicity we have created a database named “web_chat”. Create a table named “messages” and it will have just 4 fields:

  1. ID INT AUTO INCREMENT
  2. sender TEXT
  3. receiver TEXT
  4. message TEXT

Now you need to install a module named “mysql” that will be used by Node JS server. So run the following command in your terminal:

npm install mysql

Don’t forget to start the server again after installing this module: “nodemon server.js”

To use this module in Node JS, first you have to create an instance of this module and create a connection with database. Finally you can connect with your database using connection object. So paste the following lines in your “server.js”:

server.js

// Create instance of mysql
var mysql = require("mysql");

// make a connection
var connection = mysql.createConnection({
	"host": "localhost",
	"user": "root",
	"password": "",
	"database": "web_chat"
});

// connect
connection.connect(function (error) {
	// show error if any
});

To insert a new row in “messages” table, paste the following code in your “send_message” event in “server.js”:

// listen from client
socket.on("send_message", function (data) {
	// send event to receiver
	var socketId = users[data.receiver];

	io.to(socketId).emit("new_message", data);

	// save in database
	connection.query("INSERT INTO messages (sender, receiver, message) VALUES ('" + data.sender + "', '" + data.receiver + "', '" + data.message + "')", function (error, result) {
		//
	});
});

If you try to send a message now, you will see that message in “messages” too. So the INSERT operation works, now we need to show all messages from previous chat when user selected.

Show previous private chat from database

In “index.php” change the “onUserSelected” function to the following:

function onUserSelected(username) {
    // save selected user in global variable
    receiver = username;

    // call an ajax
    $.ajax({
      url: "http://localhost:3000/get_messages",
      method: "POST",
      data: {
        sender: sender,
        receiver: receiver
      },
      success: function (response) {
        console.log(response);

        var messages = JSON.parse(response);
        var html = "";
        
        for (var a = 0; a < messages.length; a++) {
          html += "<li>" + messages[a].sender + " says: " + messages[a].message + "</li>";
        }

        // append in list
        document.getElementById("messages").innerHTML += html;
      }
    });
}

It sends an AJAX request to the server sending the “sender” and “receiver” names as POST parameters, the response received in JSON so the response is parsed in Javascript objects. All messages will looped and appended in the list in the same way as appending in “sendMessage” function or in “send_message” event. In order to setup AJAX requests with POST method on Node JS server, we have to install a module named “body-parser” and we have to tell the Express instance and we will be encoding the URL. So install this module by running the following command in your terminal:

npm install body-parser

server.js

// create body parser instance
var bodyParser = require("body-parser");

// enable URL encoded for POST requests
app.use(bodyParser.urlencoded());

// enable headers required for POST request
app.use(function (request, result, next) {
	result.setHeader("Access-Control-Allow-Origin", "*");
	next();
});

// create api to return all messages
app.post("/get_messages", function (request, result) {
	// get all messages from database
	connection.query("SELECT * FROM messages WHERE (sender = '" + request.body.sender + "' AND receiver = '" + request.body.receiver + "') OR (sender = '" + request.body.receiver + "' AND receiver = '" + request.body.sender + "')", function (error, messages) {
		// response will be in JSON
		result.end(JSON.stringify(messages));
	});
});

Headers will be used to allow your client to send AJAX requests. An API will be created that will fetch all previous messages between you and your selected user and send it back to client in JSON format. And your client is already parsing the JSON and displaying in a list so no need to make further changes in “index.php”.

Using MySQL with async/await

If you are planning to use async in MySQL module, you need to install the module named “mysql2/promise”.

npm install mysql2/promise

After installation, you can include it in your Node JS file.

const mysql = require("mysql2/promise")

const pool = mysql.createPool({
	host: "localhost",
	port: 3306,
	user: "root",
	password: "",
	database: "db_name"
})

const connection = await pool.getConnection()

const [rows, fields] = await connection.query("SELECT * FROM users")

Note: Make sure to make the function async before using await command.

If you want to run the INSERT query and return the ID of the newly inserted row, you can do that by the:

const [result] = await connection.query(`INSERT INTO users (name) VALUES ('Adnan')`)

if (result) {
	const userId = result.insertId
}

Go ahead and give it a free try, the design will not look good obviously, because we haven’t done anything on the design. But the functionality will be good enough for you to understand how private chat system works and how you can send message to specific user even when you have hundreds of users connected at the same time.

Realtime Web-based Chat in Firebase

Realtime Web-based Chat in Node JS & MySQL

We will create a simple and real-time chat module in Node JS and MySQL. We will be using socket IO for real-time communication.

Why chat in Node JS ?

Node JS is a web server that runs under the most famous and widely used programming language, Javascript. As Javascript is asynchronous, so Node JS server can fulfil client requests without having to wait for previous instruction to execute. Node JS runs in non-blocking event, which means that if there is any statement that takes too much time then Node JS will not get stuck at that point rather it will move to the next statement. Node JS can generate dynamic content of a website so user does not have to refresh the page in order to see updated data. This is very useful in realtime applications such as chat apps and google maps etc.

That is why most of the chat apps are developed in Node JS.

Node JS server runs on a single executable file, that file can include other multiple files too. But the server will be executing just the main file. Typically, that file named as “server.js” or “main.js” and that depends if you wanted to have different servers in same folder. That file will be executed just once and then will keep listening to incoming events, as soon it receives a new event it will send it back to other clients. Every time you run the Node JS file, all previous variables, arrays, objects will be destroyed. That is why it is recommended to store that data in some database.

Database for Node JS

When it comes to the database, Node JS has multiple options. You can use MySQL which is famous relational database structure and it is widely used in web development all over the world. Tech giants like Facebook uses MySQL as backend database. Or you can use Mongo DB which is a relation-less data structure, here data is stored in collections and documents. Collection will be name of entity and document is a single record exist in some collection. For example, you will have a collection of user and whenever a new user registered, a new document will be created inside this collection. It is much faster than MySQL.

Or you can use a file system where everything will be saved in file, it is the least recommended method but you can use this for exporting data in external formats. You can have .CSV format which is Comma Separated Values and this type of file usually gets opened in Microsoft Excel (Windows) or Numbers (Macintosh). Similarly, you can use JSON format to store data in files and this type of files holds data in forms of arrays and objects, they are typically used for statistics, for example:

{
    users: [
        { january: 123 },
        { february: 100 },
        { march: 114 },
        { april: 138 }
    ]
}

Installation and setup

First you need to download and install Node JS server in your system. You can download it from it’s official site. After installation, you need to create a folder anywhere in your system and create a file named “server.js”. Make sure the extension of file must be “.js” because the code will be in Javascript. Write the following simple line inside this file, it will show “Hello world !” when the server runs:

server.js

console.log("Hello world !");

Open terminal (CMD) and change the directory to your project folder (cd /path/to/project/). Run the following command in the terminal:

> npm init
> npm install -g nodemon

The first command will start your project folder as Node JS project and it will ask several questions like author (your) name, version etc. Just keep hitting enter if you wanted to skip these. Second command will install nodemon module globally in your system. This is helpful because nodemon allows you to make changes in server file without having to worry to restart the server. Whenever you made any changes in server file, nodemon will automatically restart the server. Otherwise, you have to restart it manually every time you make any change in server file. Now go ahead and run the following command in your terminal, make sure your project’s directory is opened in terminal:

nodemon server.js

When you run the above command, you will see a message saying “Hello world !”. Now install the Express and Http modules in your project by running the following commands, you may need to stop the nodemon running command by hitting Ctrl + C:

> npm install express
> npm install http

After installation you need to create an instance of these modules in your “server.js” file:

// use express
var express = require("express");

// create instance of express
var app = express();

// use http with instance of express
var http = require("http").createServer(app);

To start the server, call the listen function from http object and pass the port number as a parameter. Second parameter is a function that will be called when the server starts running:

// start the server
var port = 3000;
http.listen(port, function () {
    console.log("Listening to port " + port);
});

After pasting these lines in “server.js” you need to run “nodemon server.js” again in the terminal so that the server will keep running on this port.

Socket for incoming connections

Install socket module in your project by running the following command:

> npm install socket.io

And in your “server.js” create an instance of it:

// create socket instance with http
var io = require("socket.io")(http);

To receive incoming connections, you need to attach “connection” event listener on IO object:

// add listener for new connection
io.on("connection", function (socket) {
	// this is socket for each user
	console.log("User connected", socket.id);
});

Whenever a new user connects, this function will be called and we will get it’s socket object in the function argument. We can use the socket ID to send event to specific users. Following is a list of useful functions that you can perform using these IO and socket objects:

EventPurpose
socket.to(socket.id).emit(“name”, “value”)Sends the value to specific user.
io.emit(“name”, “value”)Sends the value to all connected users.
socket.emit(“name”, “value”)Sends the value back to the user who called this event.
socket.broadcast.emit(“name”, “value”)Sends the value to all users except the one who called this event.

Sending chat message event in Node JS

Download and save the socket.io.js file in your project, create a folder named “js” where all JS files will be saved. You can download socket IO from here. Create a file named “index.html” at the root of your project’s folder and include this socket file as Javascript.

<script src="js/socket.io.js"></script>

Then you need to create an instance of socket IO with the same port number as specified in “server.js”. Paste the following code in “index.html”:

<script>
    var server = "http://localhost:3000";
    var io = io(server);
</script>

When you run the index.html in your browser, you will see in your terminal a message for new user connection with a unique socket ID. Paste the following line in your “index.html” inside script tag, it will send the event to server:

// sending message from client
io.emit("new_message", "New message");

And paste the following line in “server.js”, it will receive the event sent from server. This line must be inside IO connection event:

// server should listen from each client via it's socket
socket.on("new_message", function (data) {
	console.log("Client says", data);
});

Run the “nodemon server.js” command again to start the server and refresh the index.html page in your browser and you will see “Client says New message” in your terminal. So now you can create a form where user will enter his desired message and upon hitting submit button, that event will be fired to server. Paste the following code in “index.html” file:

<form onsubmit="return sendMessage();">
	<input id="message" placeholder="Enter message">
	<input type="submit" value="Send">
</form>

<script>
function sendMessage() {
	// get message
	var message = document.getElementById("message");

	// sending message from client
	io.emit("new_message", message.value);

	// this will prevent the form from submitting
	return false;
}
</script>

Emit event to all connected users

Now if you refresh the index.html file, you will see a form with an input field to enter message and a button. Write any message you want and click send button and you will see that message in your terminal window. Now server needs to respond back to all users that a new message has been received. First send the message from server to all connected clients:

// change in server.js inside IO "connection" event
// server should listen from each client via it's socket
socket.on("new_message", function (data) {
	// server will send message to all connected clients
	// send same message back to all users
	io.emit("new_message", data);
});

It will send the same message back to all connected clients. Now all clients must be listening from server for that event, once that event is triggered from server then all clients will show the new message. Paste the following code in “index.html” inside script tag:

// client will listen from server
io.on("new_message", function (data) {
	console.log("Server says", data);
});

Now refresh the page and open a new browser window or you can use different browsers if you have multiple browsers installed in your computer. Then open both browsers side by side. Send message from 1 browser and you will see the message in console of other browser. You can open console by right clicking in empty area and selecting “Inspect Element” option. Create a <ul> tag to display all incoming messages in a list in “index.html”:

<!--list where all messages will be displayed-->
<ul id="messages"></ul>

And paste the following code in the “new_message” event in the “index.html” file:

// client will listen from server
io.on("new_message", function (data) {

    // display message
    console.log("Server says", data);
    
    // creates a new DOM element for li tag
    var li = document.createElement("li");

    // show message in li item
    li.innerHTML = data;

    // append the message at the end of list
    var messages = document.getElementById("messages");
    messages.appendChild(li);
});

Refreshing the page and you will be able to send message from a form and it will be display on the other browser in a list. Send multiple messages and all will be displayed at the end of list. When you refresh the page you will see an empty page because the server only listens to incoming messages. In order to see old messages you can either create an array or store all messages in database. Creating an array will remove all messages when the server restarted. So we are going to save in database.

Connect chat app in Node JS, with MySQL

First you need to install a module named mysql, stop the server and run the following command in your terminal. You can stop the server by pressing Ctrl + C.

npm install mysql

Make sure to run “nodemon server.js” again to start the server.

Create a database in your phpMyAdmin named “web_chat” and inside this database create a table named “messages”. This table can have only 2 fields just for the sake of simplicity, auto increment integer “id” and TEXT “message”. ID will be used when deleting the message. Your table structure should be . Create mysql module instance in “server.js” file and start a new connection with database:

// use mysql
var mysql = require("mysql");

// create connection
var connection = mysql.createConnection({
	host: "localhost",
	user: "root",
	password: "",
	database: "web_chat"
});

connection.connect(function (error) {
	// show error, if any
});

Save messages in MySQL

In “server.js” change the “new_message” event to save the incoming message in database before notifying to all other clients:

// server should listen from each client via it's socket
socket.on("new_message", function (data) {
	console.log("Client says", data);

	// save message in database
	connection.query("INSERT INTO messages (message) VALUES ('" + data + "')", function (error, result) {
		// server will send message to all connected clients
		io.emit("new_message", {
			id: result.insertId,
			message: data
		});
	});
});

This will save the incoming message in database and return the new row inserted ID which can be used to delete the message. Similarly, change your “new_message” event in “index.html” to display the message as:

li.innerHTML = data.message;

If you try to send a message now, you will see that message will also get saved in database table. Now you need to display all previous messages to a client when connected.

Reading messages from MySQL

Download and save the jquery.js file in your project’s js folder. You can download jQuery from it’s official site and include it in your “index.html” file.

<script src="js/jquery.js"></script>

Paste the following code anywhere in the script tag in “index.html”. It sends an API request to Node JS server and display all messages returned from server. Since the data returned from server will be in JSON string, so we have to convert it back to Javascript object by parsing.

$.ajax({
	url: server + "/get_messages",
	method: "GET",
	success: function (response) {
		console.log(response);

		var messages = document.getElementById("messages");

		// parse JSON to javascript object
		var data = JSON.parse(response);
		for (var a = 0; a < data.length; a++) {
			// creates new DOM element
			var li = document.createElement("li");

			// add message content as HTML
			li.innerHTML = data[a].message;

			// append at the end of list
			messages.appendChild(li);
		}
	}
});

Now in “server.js” you need to set header to allow API requests from unknown sources. Since you are testing it from localhost and that is not known for Node JS so you can add a header for “Access-Control-Allow-Origin” and allow all origins by setting it’s value to “*”. Paste the following code outside of IO “connection” event:

// add headers
app.use(function (request, result, next) {
	result.setHeader("Access-Control-Allow-Origin", "*");
	next();
});

next() is a callback function that will attach these headers with incoming API requests. And you need to create an API for “get_messages” that will return all the saved messages in database. Paste the following code in “server.js” outside of IO “connection” event:

// create API for get_message
app.get("/get_messages", function (request, result) {
	connection.query("SELECT * FROM messages", function (error, messages) {
		// return data will be in JSON format
		result.end(JSON.stringify(messages));
	});
});

Since “result.end” can only send string data in response, so you can convert your objects into JSON string and can parse this JSON string back to Javascript objects at client side. Refresh the page and now you will see all previous messages sent in this chat using Node JS API. If you send or receive a new message it will be appended at the end of same list and upon refreshing it will not be removed, because it will already get saved in database.

Delete message

If you have used WhatsApp then you probably know about the delete message feature. Your friend sends you a message and you saw it, then he deletes it and suddenly a message appeared to you “This message has been deleted”. This can be done via Node JS where deleting message from sender will make that message removed from all other users all of a sudden. First you need to create a delete button in 2 functions, when all messages are fetched from database and when a new message has been received. Change the for loop inside “get_messages” AJAX call in “index.html” file:

// give it unique id
li.id = "message-" + data[a].id;

li.innerHTML = data[a].message;

// add delete button
li.innerHTML += "<button data-id='" + data[a].id + "' onclick='deleteMessage(this);'>Delete</button>";

Above code should be pasted inside for loop before appending the child. In your “new_message” event in “index.html”, paste the following code before appending the child:

// same here
li.id = "message-" + data.id;

li.innerHTML = data.message;

// display delete button here too
li.innerHTML += "<button data-id='" + data.id + "' onclick='deleteMessage(this);'>Delete</button>";

Now inside your <script> tag create a new function that will get the message ID and send the delete event to the server with selected message ID:

function deleteMessage(self) {
	// get message id
	var id = self.getAttribute("data-id");

	// send event to server
	io.emit("delete_message", id);
}

In your “server.js” that event will be listened and delete the message from database. After deleting, an event will be sent to all users to remove that message from list. Paste the following code in your IO “connection” event:

// attach listener to server
socket.on("delete_message", function (messageId) {
	// delete from database
	connection.query("DELETE FROM messages WHERE id = '" + messageId + "'", function (error, result) {
		// send event to all users
		io.emit("delete_message", messageId);
	});
});

Now all clients must be listening continuously for delete event and you can remove that list item as soon as user receives that event. We are making it to show “This message has been deleted” similar to WhatsApp when delete event is received from server. So paste the following code in your “index.html” script tag:

// attach listener on client
io.on("delete_message", function (id) {
	// get node by id
	var node = document.getElementById("message-" + id);
	node.innerHTML = "This message has been deleted";
});

Refresh both browsers and try to send message from one browser to anther. You will see a delete button along with message text. When you click that button from one browser, that message will gets deleted from both browsers and instead you will see a message “This message has been deleted”.

Display name with message

At this point, when you send or receive a message you only see the content of message but you also wanted to know WHO sends that message. So first create a form where user can enter his name and then that name will be sent along with his message. In your “index.html” file before send message form, create a simple form like below:

<form method="POST" onsubmit="return setUsername();">
	<input type="text" autocomplete="off" id="username" placeholder="Enter username">
	<input type="submit" value="Select">
</form>

In the same file inside the <script> tag create a function that will create a global variable named “username”:

var username = "";

function setUsername() {
    username = $("#username").val();
	
    // this will prevent the form from submitting	
    return false;
}

Now change the “sendMessage” function to the following so that it will send the username along with message to the server:

function sendMessage() {
	// get message
	var message = document.getElementById("message");

	// sending message from client
    io.emit("new_message", {
        message: message.value,
        username: username
    });

	// this will prevent the form from submitting
	return false;
}

Now in “new_message” event in same file, change the line which append the message content in <li> tag to the following:

li.innerHTML = "" + data.username + ": " + data.message;

Same goes in “get_messages” AJAX call in “index.html”, change the line which append the message content in <li> tag to the following:

li.innerHTML = "" + data[a].username + ": " + data[a].message;

The above line will display the name of user in bold and message in normal style. You can save the username in messages table in database too by first creating a column named “username” and it’s value must be TEXT. Then in “server.js” inside IO “connection” event change the socket’s “new_message” to the following:

// server should listen from each client via it's socket
socket.on("new_message", function (data) {

    // save message in database
	connection.query("INSERT INTO messages(username, message) VALUES('" + data.username + "', '" + data.message + "')", function (error, result) {
		data.id = result.insertId;
		io.emit("new_message", data);
	});
});

Conclusion

Node JS plays a very important role in web development especially in realtime environment. Apart from just creating a chat app in Node JS, you can create a notification system where someone’s activity is monitored realtime by others, or maps that share realtime live location between friends etc. If you wanted to have the chat app in Node JS with the design as above, you can download all source files from the button below. Make sure you download them and let us know if you face any issue.

Single page application in MEVN stack – Realtime chat