Real-Time Applications with Node.js and WebSockets
Published: 2023-02-17 09:02:06

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
```

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');
});
```

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>
```

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);
});

```
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!