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! Introduction: When HTTP Isn’t Enough 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 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. 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. 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 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 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 npm init -y npm install express socket.io Server code (server.js) : 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'); }); 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 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 npx create-react-app chat-client cd chat-client npm install socket.io-client Chat component (Chat.js) : 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; 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 : 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. 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 : 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. 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 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 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 }); socket.on('disconnect', () => { console.log('Disconnected. Trying to reconnect...'); socket.connect(); // Auto-reconnect }); 2. User Identity 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(); } }); // 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 3. Scaling With Redis Introduce messaging passing between different servers using Redis. npm install redis npm install redis Server code : Server code : const redis = require('redis'); const subscriber = redis.createClient(); subscriber.subscribe('chat-channel'); subscriber.on('message', (channel, message) => { io.emit('receiveMessage', message); }); 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 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. User A types: “Hello” User A types: “Hello” User B removes “o” and adds “, World” 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. The server listens for each keystroke and broadcasts it to all clients, for their respective clients to render an UPDATED document. Code Snippet : 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); }); // 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 Security Issues Ernie warns us that: “You should never use WebSockets without HTTPS/WSS!” Use WSS (WebSocket Secure) : Use WSS (WebSocket Secure) : const io = new Server(server, { cors: { origin: "https://yourdomain.com" }, }); 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. Validate all inputs so as to sanitize any data that could lead to XSS attacks. Validate all inputs so as to sanitize any data that could lead to XSS attacks. Implement rate limit on users with spamming behavior. Implement rate limit on users with spamming behavior. FAQs 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 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!