Real-Time Seat Booking/Locking System using Node.js, MongoDB, and Socket.IO (with Code Examples)
This approach gives you a scalable, real-time seat locking system using Node.js + MongoDB + Socket.IO with minimal code and strong flexibility.
In this post, we’ll build a simple real-time ticket seat booking/locking system using:
- Node.js (Backend)
- MongoDB (Database)
- Socket.IO (for real-time communication)
This system will:
- Allow users to lock seats before payment.
- Auto-update all connected clients instantly.
Folder Structure:
ticket-booking-app/
│
├── server.js → Node.js + Socket.IO backend
├── package.json → Dependencies
└── seats.json → Dummy seats (if you don’t want MongoDB yet)
Step 1: Install Required Packages:
npm init -y
npm install express socket.io mongodb
Step 2: Create MongoDB Database & Collection:
// MongoDB Connection (Embedded inside server.js later)
You can use a collection named seats with fields:
{
"_id": ObjectId,
"seatNumber": "A1",
"status": "available", // available | locked | booked
"lockedBy": null,
"lockTime": null
}
Step 3: Build Backend (server.js)
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const { MongoClient, ObjectId } = require('mongodb');
const app = express();
const server = http.createServer(app);
const io = new Server(server);
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);
const dbName = 'ticketApp';
async function main() {
await client.connect();
const db = client.db(dbName);
const seatsCollection = db.collection('seats');
io.on('connection', (socket) => {
console.log(`Client connected: ${socket.id}`);
// Handle seat lock request
socket.on('lockSeat', async (seatId) => {
const seat = await seatsCollection.findOne({ _id: new ObjectId(seatId) });
if (seat.status === 'available') {
await seatsCollection.updateOne(
{ _id: seat._id },
{
$set: {
status: 'locked',
lockedBy: socket.id,
lockTime: new Date()
}
}
);
// Broadcast updated seat to all users
io.emit('seatUpdated', {
seatId: seat._id,
status: 'locked',
lockedBy: socket.id
});
}
});
// Handle seat unlock (optional, for testing)
socket.on('unlockSeat', async (seatId) => {
await seatsCollection.updateOne(
{ _id: new ObjectId(seatId) },
{ $set: { status: 'available', lockedBy: null, lockTime: null } }
);
io.emit('seatUpdated', {
seatId,
status: 'available'
});
});
});
server.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
}
main();
Inline Explanation:
- We connect to MongoDB and use the
seatscollection. - When a user locks a seat (
lockSeat), we:- Check if it’s available.
- Mark it as
"locked"in the DB. - Broadcast the new seat status to all clients via
io.emit().
- Similarly, we allow unlocking for testing (
unlockSeat).
Step 4: Frontend Client Example (Basic Test Client)
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
<script>
const socket = io('http://localhost:3000');
// Example: Lock seat A1 (use actual ObjectId in production)
function lockSeat(seatId) {
socket.emit('lockSeat', seatId);
}
// Listen for real-time seat updates
socket.on('seatUpdated', (seat) => {
console.log('Seat status updated:', seat);
// Here, you’d update your seat map UI accordingly
});
</script>
How This Works (Recap):
- User selects seat → emits
lockSeatwith seatId. - Server locks seat in DB + broadcasts update.
- All clients update their seat UI in real-time via
seatUpdatedevent.
Pros:
- Instant updates across all users.
- No double bookings on locked seats.
- Easy to extend with booking, timeouts, etc.
Enhancements You Can Add:
- Auto-release locked seats after timeout.
- Handle payments & confirm bookings.
- Use JWT tokens to identify users.
Conclusion:
This approach gives you a scalable, real-time seat locking system using Node.js + MongoDB + Socket.IO with minimal code and strong flexibility.