In this tutorial, you will learsn how to build a real-time chat applications using nodejs with socket.io, jquery, and express js.
How to Build Real Time Chat Application using Node js, Express js, and Socket.IO
Creating a chat application using express js framework of node js is very easy, for this, you just need to create a project of node js and then install express js, socket.io, and some necessary packages, and using these, you can build real time chat application built in Node JS with socket.io:
Step 1 – Create Chat App Directory
In this step, open your terminal and execute the following command to create 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 cd mkdir public
Important Note:- Go to your project root directory and create a directory name public.
Step 3 – Create Index.html and Style.css
In this step, you need to create index.html file inside public directory and add the following code in it:
<!doctype html> <html> <head> <title>Nodejs Chat</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 inside public directory 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 chat.js file inside public directory and add the following code in 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 works, as following:
- The function
setParticipantsMessage()
displays the total number of participants currently in the chat room. log()
function logs the message in gray color text on chat window.setUsername()
function displays the user name on the chat window once he/she enter the name on initial screen where it asks for nick name.sendMessage()
sends the or broadcast 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.keydown
determines the events and accordingly it works with the events.
Step 5 – Create index.js
In this step, you need to open index.js file and add the following code into 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, '/public'))); 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 run this command open your browser and hit http://127.0.0.1:4000/
The chat.js, sytle.css, and index.html files need to be placed in a public directory, which will be in the root directory of your node js chat project. Or if there is no public folder in the root directory of your node js project then create it. And keep chat.js, sytle.css, and index.html files in it.
Conclusion
Real-time chat with node js socket.io and express js. In this tutorial, you have learned how to build real-time chat with node js socket.io, jquery, and express js.