24-Jan-2023
.
Admin
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:
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