Categories
Examples Node js

Real Time Chat Application in Node js using Scoket IO

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.

real time chat in node js simple display

Here is the terminal outputs of a new connection and disconnection of the client on server side.

node js express server real time chat console output

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.

By Abdul Rehman

My name is Abdul Rehman and I love to do Reasearch in Embedded Systems, Artificial Intelligence, Computer Vision and Engineering related fields. With 10+ years of experience in Research and Development field in Embedded systems I touched lot of technologies including Web development, and Mobile Application development. Now with the help of Social Presence, I like to share my knowledge and to document everything I learned and still learning.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.