In this Node js tutorial we will demonstrate a simple Real Time Chat application using the WebSockets and we are going to use the Socket.io
package for this. Let’s create a new node js project by creating a directory navigating to that and using the command node init -y
. After that just navigate to that folder and create a new server.js file. Install the socket.io and other related packages required
npm install ws express socket.io
Code language: CSS (css)
Now in your server.js
file put the following code
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
app.use(express.static('public'));
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
socket.on('message', (data) => {
socket.broadcast.emit('message', data);
});
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Code language: JavaScript (javascript)
Creating Real time Chat Client
Now create a new folder and call it public
. Inside this folder create a new index.html
file. In that file we are going to use the socket.io-client
library via cdn and we will create one input element to take the chat inputs, and one div to display all the broadcasted messages. As you may see in the above code we created to look for message
event, and broadcast it. We need to receive that inside our client application and in that client side if we deliver some message it would be delivered via the message broadcasting.
Here is the code that you need to add into your index.html
file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple WebRTC Text Chat</title>
</head>
<body>
<h1>Simple WebRTC Text Chat</h1>
<div id="chat">
<div id="messages"></div>
<input type="text" id="input" placeholder="Type your message...">
</div>
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"></script>
<script>
const socket = io();
const messages = document.getElementById('messages');
const input = document.getElementById('input');
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
const message = input.value.trim();
if (message.length > 0) {
socket.emit('message', message);
addMessage(message, true);
input.value = '';
}
}
});
socket.on('message', (message) => {
addMessage(message, false);
});
function addMessage(message, isOwnMessage) {
const div = document.createElement('div');
div.className = isOwnMessage ? 'own-message' : 'other-message';
div.textContent = message;
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
}
</script>
</body>
</html>
Code language: HTML, XML (xml)
Running The Real Time Chat Node.js Application
Now let’s move back to your terminal and simply run the node application like you normally do with your node projects. Or simply hit command
node server.js
Code language: CSS (css)
Now navigate to http://localhost:3000, and you will see your application running. Just simply type something in your input element and hit enter. Open another instance in new browser and you will see the connected message in your terminal. Also, if you write a new message it would be displayed on all opened browsers with same link opened.
Here is the terminal outputs of a new connection and disconnection of the client on server side.
Add little Styling to the Front End Chat application
I am going to style my post with the help of Tailwind CSS to keep it consistent for my other applications. If we want to use the TailwindCSS into our html files we can use it by including the tialwind CDNs. In my case I added it like this
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
Code language: HTML, XML (xml)
After that, you can also modify the addMessage
function as well to change the style of incoming and outgoing messages differently. Here is the modified function
function addMessage(message, isOwnMessage) {
const div = document.createElement('div');
div.className = isOwnMessage ? 'own-message text-white bg-blue-500 rounded p-2' : 'other-message text-white bg-gray-500 rounded p-2';
div.textContent = message;
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
}
Code language: JavaScript (javascript)
Also the changes are not significant but the result it. Which will surprise you will the different background colors for incoming and out going messages. For the complete styling here is the complete code with basic TailwindCSS based stylings
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple WebRTC Text Chat</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100 h-screen flex items-center justify-center">
<div class="bg-white shadow-md rounded p-6 w-full max-w-md">
<h1 class="text-2xl font-semibold mb-4">Simple WebRTC Text Chat</h1>
<div id="chat" class="flex flex-col h-full">
<div id="messages" class="flex flex-col space-y-2 mb-4 h-56 overflow-y-scroll border border-gray-300 p-2 rounded"></div>
<input type="text" id="input" placeholder="Type your message..." class="border border-gray-300 rounded py-2 px-4 focus:outline-none focus:border-blue-500">
</div>
</div>
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"></script>
<script>
const socket = io();
const messages = document.getElementById('messages');
const input = document.getElementById('input');
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
const message = input.value.trim();
if (message.length > 0) {
socket.emit('message', message);
addMessage(message, true);
input.value = '';
}
}
});
socket.on('message', (message) => {
addMessage(message, false);
});
function addMessage(message, isOwnMessage) {
const div = document.createElement('div');
div.className = isOwnMessage ? 'own-message text-white bg-blue-500 rounded p-2' : 'other-message text-white bg-gray-500 rounded p-2';
div.textContent = message;
messages.appendChild(div);
messages.scrollTop = messages.scrollHeight;
}
</script>
</body>
</html>
Code language: HTML, XML (xml)
With these changes our screen now looks something like this
Limitations
This application have lot of limitations and just to demonstrate the simple socket.io example code. You will get the idea how to transmit real time message across multiple clients via node.js server. You can easily modify this code later on and just like we did in our upcoming tutorials.