WebSocket Meaning
A WebSocket is a communication method that keeps a continuous, open connection between a client (like a browser) and a server, allowing both sides to send data to each other instantly whenever needed. In this article, We’ll learn how to build a chat app using websockets and node js.
Easy Way to Understand
Instead of repeatedly asking the server, “Do you have new data?” (like in normal HTTP), WebSocket keeps the connection alive so:
- The server can push updates instantly
- The client can send data anytime
- No need to reconnect again and again
It’s like having a live conversation instead of sending separate letters.
How It Actually Works
- The client requests a WebSocket connection
- The server accepts it (called a “handshake”)
- The connection stays open
- Data flows in both directions anytime
Why WebSockets Are Used
WebSockets are useful when you need real-time updates, such as:
- Chat applications
- Live notifications
- Online games
- Stock price updates
Building a real-time chat app sounds simple… until you actually try it.
I went in thinking, “It’s just sending messages back and forth.”
But I quickly realized: real-time systems introduce a completely different set of challenges—connections, latency, scaling, state, and unexpected edge cases.
Here’s a practical, no-fluff breakdown of what I learned while building one from scratch using WebSockets and Node.js.
Why I Chose WebSockets (and Not HTTP)
Initially, I considered using regular HTTP APIs. But here’s the problem:
- HTTP is request-response
- Chat apps need instant, two-way communication
That’s where WebSockets shine.
WebSockets create a persistent connection between client and server
Data can flow both ways instantly
Think of it like an open phone call instead of sending letters back and forth.
Chat App using Websocket: Basic Architecture
Here’s the simple structure I used:
- Frontend: HTML + JS (or React)
- Backend: Node.js
- WebSocket Library:
ws(lightweight and fast)
Flow:
- User connects → WebSocket connection opens
- User sends message → Server receives it
- Server broadcasts → All connected users receive it
Chat App using Websocket: Setting Up the WebSocket Server
I started with a minimal Node.js server using ws.
Install dependency:
npm install ws
Basic server:
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 3000 });
server.on('connection', (socket) => {
console.log('User connected');
socket.on('message', (message) => {
console.log('Received:', message.toString());
// Broadcast to all clients
server.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
});
socket.on('close', () => {
console.log('User disconnected');
});
});
This alone gives you a working real-time chat.
Frontend: Connecting to the Server
Here’s a simple browser client:
<input id="msg" placeholder="Type message..." />
<button onclick="sendMessage()">Send</button>
<ul id="chat"></ul>
<script>
const socket = new WebSocket('ws://localhost:3000');
socket.onmessage = (event) => {
const li = document.createElement('li');
li.textContent = event.data;
document.getElementById('chat').appendChild(li);
};
function sendMessage() {
const input = document.getElementById('msg');
socket.send(input.value);
input.value = '';
}
</script>
At this point, I had a working chat app in under 50 lines.
But that’s where the easy part ended.
The First Real Challenge: Managing Connections
Initially, I didn’t think much about connections. But soon I noticed:
- Users refresh → new connections are created
- Old connections may linger
- Memory usage grows
Lesson:
Always handle disconnects properly.
socket.on('close', () => {
console.log('User disconnected');
});
And avoid storing unnecessary references to sockets.
Real-Time Chat App: Broadcasting Isn’t Always Enough
At first, I broadcasted messages to everyone.
But real apps need:
- Private chats
- Rooms / groups
- User-specific events
Example: Rooms
const rooms = {};
function joinRoom(room, socket) {
if (!rooms[room]) rooms[room] = [];
rooms[room].push(socket);
}
Lesson: Design your message structure early
Example message format:
{
"type": "chat",
"room": "general",
"message": "Hello"
}
Handling JSON Messages (Important)
I made a mistake early on by sending raw strings.
Bad idea.
Always structure your messages:
socket.on('message', (data) => {
const parsed = JSON.parse(data);
if (parsed.type === 'chat') {
// handle chat
}
});
Lesson: Treat WebSocket messages like API requests.
Real-Time Chat App: Performance Lessons I Learned
1. Avoid Broadcasting Everything
Sending messages to all users doesn’t scale.
Instead:
- Send only to relevant users (rooms, private chats)
2. Keep Messages Lightweight
Don’t send unnecessary data.
Bad:
{ "user": {...fullProfile}, "message": "Hi" }
Good:
{ "userId": 1, "message": "Hi" }
3. Handle Large Number of Connections
Node.js can handle many connections, but:
- Each socket consumes memory
- Too many users → performance drops
Solution:
- Use horizontal scaling
- Add load balancer + multiple servers
Scalability: What Breaks First
When I thought about scaling, I hit a big issue:
WebSockets are stateful
That means:
- A user is connected to one server
- Other servers don’t know about that connection
Solution: Redis Pub/Sub
I used Redis to sync messages across servers:
Flow:
- User sends message → Server A
- Server A publishes to Redis
- Server B receives → sends to its clients
This makes your chat app scalable.
Mistakes I Made (So You Don’t)
1. Ignoring Error Handling
WebSockets can fail silently.
Always handle errors:
socket.on('error', (err) => {
console.error(err);
});
2. No Authentication
Initially, anyone could connect.
Fix:
- Use JWT tokens during connection
3. Sending Too Many Events
Typing events, read receipts, etc. can flood the server.
Solution:
- Throttle events
- Batch updates
4. Not Handling Reconnection
Users lose internet → app breaks.
Fix:
- Auto-reconnect logic on frontend
Real-World Features I Added Later
Once basics were done, I added:
- Typing indicators
- Online/offline status
- Message timestamps
- Basic chat history (using database)
Key Takeaways
- WebSockets are powerful but stateful and complex
- Start simple, then add features gradually
- Structure your messages properly from day one
- Scaling requires external systems (Redis, load balancing)
- Performance depends on how efficiently you send data
Final Thoughts
Building this chat app changed how I think about backend systems.
It’s not just about writing code—it’s about:
- managing connections
- handling real-time events
- designing for scale
If you’re starting out, don’t overcomplicate things.
👉 Build a simple version first
👉 Break it, improve it, scale it
That’s where the real learning happens.
Official Websocket Documentation:
https://websocket.org
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API
Read More: