Real-time applications like chat systems, collaborative tools, or live notifications require a different approach compared to traditional request-response web applications. In this article, we’ll explore how to build a real-time chat app using WebSockets and Node.js , step by step.
What Are WebSockets?
WebSockets provide a full-duplex communication channel over a single TCP connection. Unlike HTTP, where the client initiates a request and waits for a response, WebSockets enable a persistent connection that allows the server to send data to the client without being polled.
This makes WebSockets perfect for real-time applications where low latency is critical.
Setting Up the Project
Having Node.js installed let’s start by creating a new Node.js project.
1. Initialize the Project
Run the following commands to initialize a new Node.js project:
mkdir realtime-chat
cd realtime-chat
npm init -y
Copy
2. Install Dependencies
We’ll use the ws
library, a lightweight WebSocket implementation for Node.js:
npm install ws express
Copy
ws
: Provides WebSocket support.
express
: Serves the frontend for our chat app.
3. Directory Structure
Create the following directory structure:
realtime-chat/
├── public/
│ ├── index.html
│ └── script.js
├── server.js
└── package.json
Building the Backend
In the server.js
file, we’ll set up an Express server to serve our frontend and a WebSocket server for real-time communication.
const express = require ( "express" );
const http = require ( "http" );
const WebSocket = require ( "ws" );
const app = express ();
const server = http. createServer (app);
const wss = new WebSocket. Server ({ server });
// Serve static files from the public directory
app. use (express. static ( "public" ));
// Handle WebSocket connections
wss. on ( "connection" , ( ws ) => {
console. log ( "A new client connected!" );
ws. on ( "message" , ( message ) => {
console. log ( `Received: ${ message }` );
// Broadcast the message to all connected clients
wss.clients. forEach (( client ) => {
if (client.readyState === WebSocket. OPEN ) {
client. send (message);
}
});
});
ws. on ( "close" , () => {
console. log ( "A client disconnected." );
});
});
// Start the server
const PORT = 3000 ;
server. listen ( PORT , () => {
console. log ( `Server is running on <http://localhost:${ PORT }` );
});
Copy
Creating the Frontend
The frontend will be a simple HTML page with a basic chat interface.
public/index.html
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" />
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
< title >Real-Time Chat</ title >
< style >
body {
font-family : Arial , sans-serif ;
margin : 0 ;
padding : 0 ;
}
.chat {
max-width : 600 px ;
margin : 50 px auto ;
border : 1 px solid #ccc ;
padding : 20 px ;
border-radius : 5 px ;
}
.messages {
height : 300 px ;
overflow-y : scroll ;
border : 1 px solid #ccc ;
padding : 10 px ;
margin-bottom : 20 px ;
}
.messages div {
margin-bottom : 10 px ;
}
.input {
display : flex ;
}
.input input {
flex : 1 ;
padding : 10 px ;
border : 1 px solid #ccc ;
border-radius : 5 px ;
}
.input button {
padding : 10 px ;
border : none ;
background-color : #007bff ;
color : white ;
border-radius : 5 px ;
cursor : pointer ;
}
</ style >
</ head >
< body >
< div class = "chat" >
< div class = "messages" id = "messages" ></ div >
< div class = "input" >
< input type = "text" id = "messageInput" placeholder = "Type a message..." />
< button id = "sendButton" >Send</ button >
</ div >
</ div >
< script src = "script.js" ></ script >
</ body >
</ html >
Copy
public/script.js
The frontend JavaScript will handle sending and receiving messages via the WebSocket connection.
const ws = new WebSocket ( "ws://localhost:3000" );
const messagesDiv = document. getElementById ( "messages" );
const messageInput = document. getElementById ( "messageInput" );
const sendButton = document. getElementById ( "sendButton" );
// Display incoming messages
ws. onmessage = ( event ) => {
event.data. text (). then (( text ) => {
const message = document. createElement ( "div" );
message.textContent = text;
messagesDiv. appendChild (message);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
});
};
// Send a message when the button is clicked
sendButton. addEventListener ( "click" , () => {
const message = messageInput.value;
ws. send (message);
messageInput.value = "" ;
});
// Handle the Enter key
messageInput. addEventListener ( "keypress" , ( event ) => {
if (event.key === "Enter" ) {
sendButton. click ();
}
});
Copy
Running the Application
Start the server:
node server.js
Copy
Open http://localhost:3000
in your browser.
Open multiple browser tabs and start chatting! Messages will appear in real time across all connected clients.
Next Steps
This is a basic real-time chat app to get you started with WebSockets. You can extend it further:
Add user authentication.
Store messages in a database.
Deploy the application to a cloud platform like Vercel or AWS.
WebSockets are a powerful tool for building real-time applications. With this foundational example, you’re ready to explore more complex use cases!