How to Build Chat Application With Socket.io Using Node Js Express?

24-Jan-2023

.

Admin

How to Build Chat Application With Socket.io Using Node Js Express?

Hello Friends,

In this article, we will be using Socket.io and HarperDB to build a full-stack, real-time chat application with chat rooms.

This will be a great project to learn how to put together full-stack apps, and how to create an app where the backend can communicate with the frontend in real-time.

Step 1: Create Chat App Directory


In this step, open your terminal and execute the following command to create a chat app directory:

mkdir chat-app

Step 2: Install Node Express JS, Socket.io, and jQuery

In this step, you need to install node js express and jquery in your chat app. So, execute the following command:

cd chat-app

npm init -y

npm install

npm install express

npm install jquery

npm install socket.io

Step 3: Create Index.html and Style.css

In this step, you need to create index.html file and add the following code into it:

<!doctype html>

<html>

<head>

<title>How to Build Chat Application With Socket.io Using Node Js Express? - Nicesnippets.com</title>

<link rel="stylesheet" href="style.css">

</head>

<body>

<ul class="pages">

<li class="chat page">

<div class="chat_area">

<ul class="messages"></ul>

</div>

<input class="input_message" placeholder="Type here..."/>

</li>

<li class="login page">

<div class="form">

<h3 class="title">What's your nickname?</h3>

<input class="username_input" type="text" maxlength="14" />

</div>

</li>

</ul>

<script src="//code.jquery.com/jquery-3.5.0.js"></script>

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

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

</body>

</html>

After that, create style.css file and add the following code into it:

* { margin: 0; padding: 0; box-sizing: border-box; }

body { font: 13px Helvetica, Arial; }

ul {

list-style: none;

word-wrap: break-word;

}

.log {

color: gray;

}

.pages {

height: 100%;

/*margin: 0;

padding: 0;*/

width: 100%;

}

.page {

height: 100%;

position: absolute;

width: 100%;

}

.login.page {

background-color: #000;

}

.login.page .form {

height: 100px;

margin-top: -100px;

position: absolute;

text-align: center;

top: 50%;

width: 100%;

}

.login.page .form .username_input {

background-color: transparent;

border: none;

border-bottom: 2px solid #fff;

outline: none;

padding-bottom: 15px;

text-align: center;

width: 400px;

}

.login.page .title {

font-size: 200%;

}

.login.page .username_input {

font-size: 200%;

letter-spacing: 3px;

}

.login.page .title, .login.page .username_input {

color: #fff;

font-weight: 100;

}

.chat.page {

display: none;

}

.input_message {

font-size: 100%;

}

.chat_area {

height: 100%;

padding-bottom: 60px;

}

.messages {

height: 100%;

margin: 0;

font-size: 150%;

overflow-y: scroll;

padding: 10px 20px 10px 20px;

}

.message.typing .message_body {

color: gray;

}

.username {

font-weight: 700;

overflow: hidden;

padding-right: 15px;

text-align: right;

}

.input_message {

border: 10px solid #000;

bottom: 0;

height: 60px;

left: 0;

outline: none;

padding-left: 10px;

position: absolute;

right: 0;

width: 100%;

}

Step 4: Create Chat.js

In this step, you need to create a chat.js file and add the following code to it:

$(function() {

var win = $(window);

var usernameInput = $('.username_input'); // Input for username

var messages = $('.messages'); // Messages area

var inputMessage = $('.input_message'); // Input message input box

var loginPage = $('.login.page'); // The login page

var chatPage = $('.chat.page'); // The chatroom page

var username;

var connected = false;

var typing = false;

var currentInput = usernameInput.focus();

var socket = io();

const setParticipantsMessage = (data) => {

var message = '';

if (data.numberOfUsers === 1) {

message += "There is 1 participant";

} else {

message += "There are " + data.numberOfUsers + " participants";

}

log(message);

}

const log = (message, options) => {

var el = $('<li>').addClass('log').text(message);

addMessageElement(el, options);

}

const setUsername = () => {

username = cleanInput(usernameInput.val().trim());

if (username) {

loginPage.fadeOut();

chatPage.show();

loginPage.off('click');

currentInput = inputMessage.focus();

socket.emit('user_added', username);

}

}

const sendMessage = () => {

var message = cleanInput(inputMessage.val());

if (message && connected) {

inputMessage.val('');

addChatMessage({

username: username,

message: message

});

socket.emit('new_message', message);

}

}

const addChatMessage = (data, options) => {

var typingMessages = getTypingMessages(data);

options = options || {};

if (typingMessages.length !== 0) {

options.fade = false;

typingMessages.remove();

}

var usernameDiv = $('<span class="username"/>').text(data.username).css('font-weight', 'bold');

var messageBodyDiv = $('<span class="messageBody">').text(data.message);

var typingClass = data.typing ? 'typing' : '';

var messageDiv = $('<li class="message"/>').data('username', data.username).addClass(typingClass).append(usernameDiv, messageBodyDiv);

addMessageElement(messageDiv, options);

}

const addChatTyping = (data) => {

data.typing = true;

data.message = 'is typing';

addChatMessage(data);

}

const removeChatTyping = (data) => {

getTypingMessages(data).fadeOut(function () {

$(this).remove();

});

}

const addMessageElement = (el, options) => {

var el = $(el);

// Setup default options

if (!options) {

options = {};

}

if (typeof options.fade === 'undefined') {

options.fade = true;

}

if (typeof options.prepend === 'undefined') {

options.prepend = false;

}

// Apply options

if (options.fade) {

el.hide().fadeIn(150);

}

if (options.prepend) {

messages.prepend(el);

} else {

messages.append(el);

}

messages[0].scrollTop = messages[0].scrollHeight;

}

const cleanInput = (input) => {

return $('<div/>').text(input).html();

}

const updateTyping = () => {

if (connected) {

if (!typing) {

typing = true;

socket.emit('typing');

}

}

}

const getTypingMessages = (data) => {

return $('.typing.message').filter(function (i) {

return $(this).data('username') === data.username;

});

}

win.keydown(event => {

//console.log('event.which: ' + event.which);

// Auto-focus the current input when a key is typed

if (!(event.ctrlKey || event.metaKey || event.altKey)) {

currentInput.focus();

}

// When the client hits ENTER on their keyboard

if (event.which === 13) {

if (username) {

sendMessage();

socket.emit('typing_stop');

typing = false;

} else {

setUsername();

}

}

inputMessage.on('input', () => {

updateTyping();

});

loginPage.click(() => {

currentInput.focus();

});

inputMessage.click(() => {

inputMessage.focus();

});

socket.on('login', (data) => {

connected = true;

var message = "Welcome to Nodejs Chat Room";

log(message, {

prepend: true

});

setParticipantsMessage(data);

});

socket.on('new_message', (data) => {

addChatMessage(data);

});

socket.on('user_joined', (data) => {

log(data.username + ' joined');

setParticipantsMessage(data);

});

socket.on('user_left', (data) => {

log(data.username + ' left');

setParticipantsMessage(data);

removeChatTyping(data);

});

socket.on('typing', (data) => {

addChatTyping(data);

});

socket.on('typing_stop', (data) => {

removeChatTyping(data);

});

socket.on('disconnect', () => {

log('You have been disconnected');

});

socket.on('reconnect', () => {

log('You have been reconnected');

if (username) {

socket.emit('user_added', username);

}

});

socket.on('reconnect_error', () => {

log('Attempt to reconnect has failed');

});

});

Note that The chat.js functions will work, as follows:

  • The function setParticipantsMessage() displays the total number of participants currently in the chat room.
  • log() function logs the message in the gray color text on the chat window.
  • setUsername() function displays the user name on the chat window once he/she enters the name on the initial screen where it asks for a nickname.
  • sendMessage() sends or broadcasts the message to the active participants.
  • addChatMessage() adds the message to the chat window. While someone is typing it shows the person is typing otherwise once typing is done it sends the message to the window.
  • addChatTyping() shows while someone is typing.
  • removeChatTyping() removes typing once someone has just finished typing and hit the enter key.
  • win. key down determines the events and accordingly it works with the events.
  • Step 5: Create index.js

    In this step, you need to open the index.js file and add the following code to it:

    var path = require('path');

    var express = require('express');

    var app = express();

    var server = require('http').Server(app);

    var io = require('socket.io')(server);

    var port = process.env.PORT || 4000;

    server.listen(port, function(){

    console.log('Listening on %d:' + port);

    });

    app.use(express.static(path.join(__dirname, 'static')));

    var numberOfUsers = 0;

    io.on('connection', (socket) => {

    var userJoined = false;

    socket.on('new_message', (msg) => {

    socket.broadcast.emit('new_message', {

    username: socket.username,

    message: msg

    });

    });

    socket.on('user_added', (username) => {

    if (userJoined) return;

    socket.username = username;

    userJoined = true;

    numberOfUsers++;

    socket.emit('login', {

    numberOfUsers: numberOfUsers

    });

    socket.broadcast.emit('user_joined', {

    username: socket.username,

    numberOfUsers: numberOfUsers

    });

    });

    socket.on('typing', () => {

    socket.broadcast.emit('typing', {

    username: socket.username

    });

    });

    socket.on('typing_stop', () => {

    socket.broadcast.emit('typing_stop', {

    username: socket.username

    });

    });

    socket.on('disconnect', () => {

    if (userJoined) {

    --numberOfUsers;

    socket.broadcast.emit('user_left', {

    username: socket.username,

    numberOfUsers: numberOfUsers

    });

    }

    });

    });

    Step 6: Run Development Server

    You can use the following command to run the development server:

    //run the below command

    npm start

    After running this command open your browser and hit

    http://127.0.0.1:3000/

    I hope it can help you...

    #Node.js Express

    #Node JS