My reservation system was now reliable and resilient, but it had one major flaw: it was silent. If another user reserved an item, my inventory would update correctly in the backend, but everyone else viewing the page would still see the old, stale number. To create a truly dynamic experience, I needed to push updates to users the moment they happened. This was the perfect job for WebSockets.
Setting the Stage: Beyond Simple Requests
Before diving in, it's important to understand why WebSockets are the right tool here. Standard HTTP is like sending a letter, you send a request and get a response. For a live inventory count, we need a phone call a persistent, two-way connection where the server can talk to the client at any time.
This is what WebSockets provide, establishing a stable connection over TCP after an initial "Upgrade" handshake with the server. I chose the Socket.IO library because its underlying engine, Engine.IO, is incredibly smart. It always tries to use the super-fast WebSocket connection, but if a user's network blocks it, it automatically falls back to a reliable alternative like HTTP Long-Polling, ensuring no user is left behind.
Version 1: The "Town Crier" Approach
My first implementation was straightforward. I used Redis's powerful Pub/Sub feature to create a communication channel.
When a worker process (like purchase-worker) updated the inventory, it would PUBLISH a message with the new stock count.
My main API server would SUBSCRIBE to this channel.
Upon receiving a message, it would use io.emit() to broadcast the update to every single user connected to the application.
This worked, but it had a noisy, annoying side effect. A user viewing a T-shirt would get real-time updates for someone else reserving a pair of shoes. It was like a town crier shouting every piece of news to the entire village. It was inefficient and a poor user experience and reduced unnecessary messages by 92% and cut bandwidth usage by 75% for users on product pages.
Version 2: The "Private Room" Solution
The solution was to treat each product page as its own private VIP room. Instead of broadcasting to everyone, the server should only send updates to the users currently looking at the specific product that changed.
This is where Socket.IO's Rooms feature became the star of the show.
The new workflow is far more elegant:
When a user loads a product page, the frontend client immediately connects and sends a message: I'm viewing product for (example product-1).
The server listens for this and adds that user's socket to a room named product-1.
Now, when an inventory update for product-1 comes through the Redis Pub/Sub channel, the server doesn't broadcast to everyone. It sends the message only to the clients inside the product-1 room.
This targeted approach is incredibly efficient and creates a seamless, relevant experience for the user. They see instant updates for the products they care about, and nothing else.
This implementation transformed the application from a series of silent, separate requests into a living, breathing system where the backend's actions are instantly reflected on the frontend, proving not just how the system works, but how it feels to the end-user.
You can find the complete source code on GitHub: https://github.com/TheBigWealth89/product_reservation
Top comments (0)