DEV Community

Cover image for Real-Time Applications with Node.js and WebSockets
Bliss Abhademere
Bliss Abhademere

Posted on

Real-Time Applications with Node.js and WebSockets

Real-time web applications have gained popularity in recent years. These programs provide real-time data flow without the need to repeatedly refresh web pages by facilitating smooth communication between clients and servers. Due to their scalability, speed, and user-friendliness, Node.js and related technologies, like Express and WebSockets, are preferred options for developing real-time applications.

What is WebSockets?

WebSockets is a protocol for two-way communication between a client and a server, allowing data to be sent and received in real time. WebSockets overcome the limitations of traditional HTTP communication, which requires establishing a new connection for each request. WebSockets enable the establishment of a persistent connection, which allows data to be delivered and received at any time, without the need to initiate a new connection.
Building a Real-Time Application with Node.js and WebSockets
In this article, we'll use Node.js, Express, and WebSockets to create a straightforward real-time chat application. The application will allow multiple users to communicate in real time.

Prerequisites

Before we begin, ensure that you have the following installed:

  • Node.js
  • npm
  • Express
  • Socket.IO

Setting up the Project
First, create a new directory for your project and initialize it with npm:

mkdir real-time-chat
cd real-time-chat
npm init
Enter fullscreen mode Exit fullscreen mode

Install the required packages:

npm install express socket.io --save

Create a new file named server.js and add the following code:

const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);

app.use(express.static(__dirname + '/public'));

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/public/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');

  socket.on('disconnect', () => {
    console.log('user disconnected');
  });

  socket.on('chat message', (msg) => {
    console.log('message: ' + msg);
    io.emit('chat message', msg);
  });
});

server.listen(3000, () => {
  console.log('listening on *:3000');
});
Enter fullscreen mode Exit fullscreen mode

We import the needed package in this code., set up the Express app, and create a new server using the http module. We also set up the Socket.IO server, which allows us to communicate in real-time with our clients.
Static files are supplied from the specified directory by the app.use() function. This instance is serving files from the public directory.

The app.get() method sets up a route to the home page, which provides access to the public directory's index.html file.
A connection listener is established by the io.on() method, which watches for connections from clients.

When a client disconnects, an event called "disconnect" is released, and the socket.on() procedure watches for it. We log a note to the console whenever a client disconnects.

The "chat message" event, which is released whenever a client sends a message, is also monitored by the socket.on() method.
When a message is received, we emit it to all clients using io.emit()and log it to the console.

Finally, we launch the server and open port 3000 for listening.

Creating the Frontend

Create a new directory called public, and add a new file called index.html to it. The code below should be added to this file:

<!DOCTYPE html>
<html>
  <head>
    <title>Real-Time Chat Application</title>
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <div class="chat-container">
      <header>
        <h1>Real-Time Chat Application</h1>
      </header>
      <main class="chat-window">
        <ul class="message-list"></ul>
        <form id="message-form">
          <input type="text" name="message" placeholder="Type your message here">
          <button>Send</button>
        </form>
      </main>
    </div>
    <script src="/socket.io/socket.io.js"></script>
    <script src="script.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

In this HTML file, we create the structure for the chat interface. We have a header that displays the application's name, a "main" element with the chat window and a message-sending form, and a script tag that loads the socket.io client library and our client-side JavaScript file.
Creating a form to send messages requires the use of the <form> tag. We'll attach a listener to it when the form is submitted because it has an id attribute with the value "message-form" set.

A placeholder attribute on the form's <input> tag with the name "message" prompts the user to "Type your message here" as a hint.

Additionally, there is a "Send"-labeled <button> tag that the user can click to submit the form.

In the <script> tag, we'll create a new instance of the socket.io client and attach event listeners for the form submission and receiving chat messages. Let's add the script.js file and add the following code:

const socket = io();

// Handle form submission
const form = document.getElementById('message-form');
form.addEventListener('submit', e => {
  e.preventDefault();
  const messageInput = form.elements.message;
  const message = messageInput.value.trim();
  if (message) {
    socket.emit('chat message', message);
    messageInput.value = '';
  }
});

// Handle incoming chat messages
const messageList = document.querySelector('.message-list');
socket.on('chat message', message => {
  const li = document.createElement('li');
  li.textContent = message;
  messageList.appendChild(li);
});

Enter fullscreen mode Exit fullscreen mode

In this client-side JavaScript code, we first create a new instance of the socket.io client using io(). Then, we attach an event listener for the form submission using addEventListener(). Inside the event listener, we prevent the default form submission behavior using e.preventDefault(), get the message input using form.elements.message, and emit a chat message event with the message to the server using socket.emit(). We also clear the message input value using messageInput.value = " ".
We also attach an event listener for receiving chat messages using socket.on(). Inside the event listener, we create a new list item element using document.createElement() and add the received message as text content using li.textContent. Then, we append the list item to the message list using messageList.appendChild(li).

Conclusion

With this code, we have a functional real-time chat application that allows users to send and receive messages in real-time. We can start the server using node index.js and navigate to http://localhost:3000 in a web browser to test it out.
Congratulations on building your first real-time application with Node.js, Express, and WebSockets!

Top comments (0)