Building Real-Time Applications with Express WebSocket

Learn how to build real-time applications using Express and WebSocket. This guide covers integration, setup, and best practices for seamless real-time communication..

What is WebSocket?

WebSocket is a protocol that enables persistent, bidirectional communication between a client and a server over a single, long-lived connection. Unlike HTTP, which follows a request-response model,

WebSocket

allows for real-time data transfer with low latency, making it ideal for applications that require live updates, such as chat apps, gaming, and real-time analytics. This persistent connection reduces the overhead associated with establishing multiple HTTP connections, leading to more efficient and faster communication.
In this article, we will explore how to integrate WebSocket with Express to build applications that require real-time capabilities, such as live chat applications, live notifications, and collaborative tools. By the end of this guide, you will have a clear understanding of setting up a WebSocket server with Express, handling client connections, and implementing real-time features in your applications.

Setting Up Your Environment

Before diving into the integration, ensure you have Node.js and npm installed on your machine. If not, download and install them from the

official Node.js website

. Next, create a new directory for your project and initialize a new Node.js project:

bash

1mkdir express-websocket
2cd express-websocket
3npm init -y
Install the necessary packages:

bash

1npm install express ws

Initializing Express Application

First, set up a basic Express application. Create a new file named server.js and add the following code to initialize your Express server and integrate WebSocket:

JavaScript

1const express = require('express');
2const http = require('http');
3const WebSocket = require('ws');
4
5const app = express();
6const server = http.createServer(app);
7const wss = new WebSocket.Server({ server });
8
9app.get('/', (req, res) => {
10  res.send('WebSocket server running...');
11});
12
13server.listen(3000, () => {
14  console.log('Server started on port 3000');
15});
This code initializes an Express application, creates an HTTP server, and sets up a WebSocket server on top of it.

Creating a WebSocket Server

Now, let's handle WebSocket connections by setting up the WebSocket server to listen for and respond to messages from clients. Add the following code to server.js:

JavaScript

1wss.on('connection', (ws) => {
2  console.log('Client connected');
3  
4  ws.on('message', (message) => {
5    console.log(`Received: ${message}`);
6    ws.send(`Hello, you sent -> ${message}`);
7  });
8
9  ws.on('close', () => {
10    console.log('Client disconnected');
11  });
12});
This snippet sets up event listeners for new connections, incoming messages, and connection closures, enabling bidirectional communication.

Integrating WebSocket with Express Routes

To demonstrate how Express and WebSocket can work together, let's create an endpoint that sends a message to all connected WebSocket clients. Modify your server.js file as follows:

JavaScript

1app.use(express.json());
2
3app.post('/send', (req, res) => {
4  const message = req.body.message;
5  wss.clients.forEach((client) => {
6    if (client.readyState === WebSocket.OPEN) {
7      client.send(message);
8    }
9  });
10  res.send('Message sent to all clients');
11});
This code adds a new POST endpoint /send that takes a message from the request body and broadcasts it to all connected WebSocket clients.

Building a Real-time Chat Application with Express-WS

Now, let's build a simple real-time chat application. Create an HTML file named index.html:

HTML

1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <meta charset="UTF-8">
5  <title>WebSocket Chat</title>
6</head>
7<body>
8  <input id="message" type="text" placeholder="Type a message..." />
9  <button onclick="sendMessage()">Send</button>
10  <div id="chat"></div>
11
12  <script>
13    const ws = new WebSocket('ws://localhost:3000');
14
15    ws.onmessage = (event) => {
16      const chat = document.getElementById('chat');
17      chat.innerHTML += `<p>${event.data}</p>`;
18    };
19
20    function sendMessage() {
21      const message = document.getElementById('message').value;
22      ws.send(message);
23    }
24  </script>
25</body>
26</html>
This HTML file includes an input field for typing messages, a button to send messages, and a div to display chat messages. The JavaScript code establishes a WebSocket connection to the server, listens for incoming messages, and updates the chat div with received messages.

Get Free 10,000 Minutes Every Months

No credit card required to start.

Handling Errors and Edge Cases

WebSocket communication can encounter various errors and edge cases, such as network issues or unexpected disconnections. It's essential to handle these gracefully to maintain a robust application. For instance, you can add error handling and reconnection logic:

JavaScript

1ws.onerror = (error) => {
2  console.error('WebSocket error:', error);
3};
4
5ws.onclose = (event) => {
6  console.log('WebSocket closed:', event);
7  // Optionally implement reconnection logic
8};
By capturing errors and connection closures, you can improve the stability and user experience of your WebSocket application.

Scaling WebSocket Servers

As your application grows, you may need to scale your WebSocket server to handle increased traffic. Load balancing WebSocket connections can be achieved using tools like NGINX or HAProxy. Additionally, consider using a pub/sub messaging system like Redis to manage communication between multiple WebSocket servers. Here’s a basic example of using Redis with WebSocket:

JavaScript

1const redis = require('redis');
2const publisher = redis.createClient();
3
4wss.on('connection', (ws) => {
5  ws.on('message', (message) => {
6    publisher.publish('chat', message);
7  });
8});
9
10const subscriber = redis.createClient();
11subscriber.subscribe('chat');
12subscriber.on('message', (channel, message) => {
13  wss.clients.forEach((client) => {
14    if (client.readyState === WebSocket.OPEN) {
15      client.send(message);
16    }
17  });
18});
This setup allows you to distribute messages across multiple WebSocket servers, ensuring scalability and reliability for your real-time application.

Conclusion

Integrating WebSocket with Express is a powerful way to build real-time web applications that require instantaneous data transfer and communication. By following the steps outlined in this guide, you can set up a basic WebSocket server, handle client connections, and create a simple real-time chat application. Moreover, addressing potential errors and scaling your server will ensure that your application remains robust and efficient. Whether you're building a chat app, a live feed, or any other real-time feature, Express and WebSocket provide the tools you need to succeed.

Want to level-up your learning? Subscribe now

Subscribe to our newsletter for more tech based insights

FAQ