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.

Real-Time Seat Booking/Locking System
Real-Time Seat Booking/Locking System

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 seats collection.
  • When a user locks a seat (lockSeat), we:
    1. Check if it’s available.
    2. Mark it as "locked" in the DB.
    3. 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):

  1. User selects seat → emits lockSeat with seatId.
  2. Server locks seat in DB + broadcasts update.
  3. All clients update their seat UI in real-time via seatUpdated event.

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.