Introduction: When HTTP Isn’t Enough
Together, Bert and Ernie, two friends are working on the side project of their dreams: a chat app that enables real-time conversations for teams who work remotely. The front-end coder Bert can hardly contain himself as he shares shiny new features with his backend specialist friend. “Look! I can type a message, and it gets sent to the server, and I can see a response popping up nearly instantly!” Ernie, the backend guru, frowns. “But how do you solve the issue of two people trying to have a conversation at the same time? Your app keeps refreshing the page instead of letting you ‘see’ the conversation, which makes it impossible to chat in real-time .”
The challenge is that Bert’s app operates on HTTP in which a client must request a fetch from the server. Ernie summaries: “It’s like all your friends are texting you back, but then, suddenly, you can’t see any of the replies until you refresh to check if there are new messages because they can’t see your last message until you refresh it and that is how HTTP works!”
Here comes the best part: for full-stack apps that work in real-time, there is WebSockets. This part is super exciting, so let’s join Ernie and Bert and find out how WebSockets function, their implementation procedures, the reasoning behind their importance, and so much more.
What Are WebSockets? A Beginner’s Breakdown
WebSockets are similar to a continuous phone call between a client (your web browser) and a server. They differ from the HTTP protocol which functions in the manner of, “send a letter, wait for a reply.” With WebSockets, both parties can converse freely as they please. The features of WebSockets include the following:
- Full-duplex: It is possible for both the client and server to transmit data simultaneously.
- Low latency: There are no excessive repeated handshakes; data can flow freely.
- Lightweight: Messages are small which reduces bandwidth usage.
Example: Picture a constantly updating sports scoreboard. With HTTP, the client constantly has to spam the server every second, “Any score change?” With WebSockets, the server announces,” GOAL!” the instant it happens.
WebSockets vs. HTTP: What’s the New Hotness?
Bert sits back and scratches his head. “But HTTP works fine for most apps. Why move the goalposts?” Ernie laughs softly, takes a marker, and begins writing something on the whiteboard.
“Let’s start from the top,” he says. “Let’s say real-time life updates, such as live sports scores. Clients need to ask the server every second: ‘Is there anything I need to know?’ That is polling, so every thirty seconds, you have to ask, ‘Are we meeting?’ Ridiculous, no? It also uses a lot of bandwidth.”
WebSockets turn this around:
- Real-time Updates: Data on the server is sent the moment it changes; no polling necessary.
- Chat applications: No refreshing the page required. Messages flood in as you type.
- Multiplayer video games: No more stuttery movements. Actions get displayed on screens seamlessly.
“HTTP is fairly decent at dealing with static things such as a blog or product page. When it comes to live interactions though, a persistent connection is required. WebSockets.”
Creating A Real-Time Chat App: The Good Stuff Begins
Ernie cleans his glasses. “So, let’s make a simple chat application,” Ernie exclaims. “We will have a Node.js server for the backend and a React app for the frontend. Ready?”
1. Create Socket.IO Backend
“Grab a Node.js server because you are going to need it for the Socket.IO part,” Ernie says as he types really quickly:
npm init -y
npm install express socket.io
Server code (server.js) :
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = new Server(server);
// Serve static files (like React's build folder)
app.use(express.static('public'));
// Handle WebSocket connections
io.on('connection', (socket) => {
console.log('New user connected:', socket.id);
// Listen for Incoming messages from the socket
socket.on('sendMessage', (message) => {
console.log('Received:', message);
// Broadcast the message to everyone
io.emit('receiveMessage', message);
});
// Handle user disconnects events
socket.on('disconnect', () => {
console.log('User left:', socket.id);
});
});
server.listen(3000, () => {
console.log('Visit http://localhost:3000 on a browser, Server started successful on port 3000');
});
“The client and server are able to communicate with each other thanks to Socket.IO’s handling of WebSocket connections. When the client calls the (sendMessage) function, the server sends the message to everyone connected through (io.emit). Pretty straightforward, isn’t it?”
2. Frontend with React
“It’s my turn now. Let’s get to work on the React client,” says Bert.
npx create-react-app chat-client
cd chat-client
npm install socket.io-client
Chat component (Chat.js) :
import { useState, useEffect } from 'react';
import io from 'socket.io-client';
// Connect to the server
const socket = io('http://localhost:3000');
function Chat() {
const [message, setMessage] = useState('');
const [messages, setMessages] = useState([]);
useEffect(() => {
// Listen for new messages
socket.on('receiveMessage', (newMessage) => {
setMessages([...messages, newMessage]);
});
}, [messages]);
const sendMessage = () => {
if (message.trim()) {
socket.emit('sendMessage', message);
setMessage('');
}
};
return (
<div style={{ padding: '20px' }}>
<div>
{messages.map((msg, index) => (
<p key={index}>{msg}</p>
))}
</div>
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
/>
<button onClick={sendMessage}>Send</button>
</div>
);
}
export default Chat;
How It Works :
- Messages are sent by the server over a WebSocket to any clients that are connected.
- The React application is a single-page application that is able to refresh the UI without reloading the page.
Test It :
- To start the server, enter node server.js in the console.
- To start the React application, enter npm start in the console.
- With two tabs open on a browser, type a message in one tab and notice how almost instantly, the other tab will display the same message.
Real-Life Uses Examples
This is what Bert intended to build based on the application, but Ernie mentions, “Most real-life applications need a bit of mistake handling and a way to expand the framework for development.” Let’s see some probable problems.
1. Line Of Connection Stops
Implement a reconnection strategy in the React client.
socket.on('disconnect', () => {
console.log('Disconnected. Trying to reconnect...');
socket.connect(); // Auto-reconnect
});
2. User Identity
Secure WebSocket using authenticated JWT tokens.
// On login, send a token
socket.emit('authenticate', { token: 'USER_JWT' });
// Server verifies token
socket.on('authenticate', ({ token }) => {
if (isValidToken(token)) {
socket.authenticated = true;
} else {
socket.disconnect();
}
});
3. Scaling With Redis
Introduce messaging passing between different servers using Redis.
npm install redis
Server code :
const redis = require('redis');
const subscriber = redis.createClient();
subscriber.subscribe('chat-channel');
subscriber.on('message', (channel, message) => {
io.emit('receiveMessage', message);
});
Beyond Chat: Editing a shared document
This is Bert’s next idea – an editor similar to Google Docs. Ernie says, “You can use web sockets to listen for changes made by different people and merge them.”
For Example :
-
User A types: “Hello”
-
User B removes “o” and adds “, World”
-
The server listens for each keystroke and broadcasts it to all clients, for their respective clients to render an UPDATED document.
Code Snippet :
// Client sends keystrokes
textarea.addEventListener('input', (e) => {
socket.emit('textChange', e.target.value);
});
// Server broadcasts changes
socket.on('textChange', (text) => {
io.emit('updateText', text);
});
Security Issues
Ernie warns us that: “You should never use WebSockets without HTTPS/WSS!”
- Use WSS (WebSocket Secure) :
const io = new Server(server, { cors: { origin: "https://yourdomain.com" }, });
-
Validate all inputs so as to sanitize any data that could lead to XSS attacks.
-
Implement rate limit on users with spamming behavior.
FAQs
Q: Is the speed of WebSockets much better than that of HTTP?
A: Yes! For instantaneous applications, WebSockets are the best because they remove the need to conduct polling.
Q: Is it possible to utilize REST APIs together with WebSockets?
A: Yes, definitely! Use WebSockets with live updates and REST for performing CRUD operations.
Q: How do I deal with a server crashing?
A: Clients can automatically reconnect (see reconnection logic above).
Final Words
Bert’s chat app now pings with real-time charm and Ernie smiles with satisfaction. WebSockets are not only for chats, but also serve the purpose of live dashboards, gaming, IoT, and more.
Your Turn: Go ahead and try out the examples, destroy them, and create something new. Your real-time apps are waiting!