Real time chat with nodejs socket.io and expressjs. In this tutorial, you will learn how to build real time chat with nodejs socket.io, jquery and expressjs.
This tutorial will help you step by step to on how to build chat application using Nodejs, Express and Socket.IO.
How to build real time chat application using Node js, Express js and Socket.IO
Follow the following steps and build real time chat with node js socket.io and express js:
- Step 1 – Create Chat App Directory
- Step 2 – Install Node Express JS, Socket.io and jQuery
- Step 3 – Create Index.html and Style.css
- Step 4 – Create Chat.js
- Step 5 – Create index.js
- Step 6 – Run Development Server
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
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>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 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 and add the following code into 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, '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 development server:
//run the below command npm start after run this command open your browser and hit http://127.0.0.1:3000/
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.