REAL-TIME ARCHITECTURE

Real-Time WebSockets (Socket.io)

Definition: WebSocket is a computer communications protocol, providing full-duplex, bi-directional communication channels over a single TCP connection.

সাধারণ HTTP রিকোয়েস্ট হলো "One-way" যোগাযোগ (ক্লায়েন্ট চাইল, সার্ভার দিল)। কিন্তু চ্যাট অ্যাপ বা লাইভ ড্যাশবোর্ডের ক্ষেত্রে সার্ভার থেকে সরাসরি ক্লায়েন্টকে ডেটা পুশ (Push) করার জন্য আমাদের একটি রিয়েল-টাইম পাইপলাইন প্রয়োজন হয়।

1. The HTTP Overhead Problem

The Polling Trap

ধরি, আমরা একটি স্টক মার্কেট লাইভ ড্যাশবোর্ড বানাচ্ছি। অনেক নতুন ডেভেলপার `setInterval` দিয়ে প্রতি ১ সেকেন্ড পর পর এপিআই কল করে ডেটা আপডেট করে (যাকে HTTP Polling বলে)। সমস্যা হলো, প্রতিটি HTTP রিকোয়েস্টের সাথে বিশাল সাইজের Headers, Cookies, এবং Handshake overhead যায়।

১০০০ জন ইউজার থাকলে প্রতি সেকেন্ডে ১০০০ রিকোয়েস্ট! সার্ভার খামোখাই ওভারলোড হয়ে ক্র্যাশ করবে। WebSocket এর সলিউশন: এটি একবার হ্যান্ডশেক (Handshake) করে একটি পার্মানেন্ট কানেকশন তৈরি করে রাখে। এরপর ডেটাগুলো কোনো হেডার ছাড়াই লাইটওয়েট ফ্রেম (Frame) হিসেবে আদান-প্রদান হয়।

HTTP Short/Long Polling

  • ক্লায়েন্ট বারবার সার্ভারকে জিজ্ঞেস করে "নতুন ডেটা আছে?"
  • অপ্রয়োজনীয় নেটওয়ার্ক ওভারহেড তৈরি হয়।
  • ১০০% রিয়েল-টাইম নয় (ডিলে থাকে)।

WebSocket Protocol (ws://)

  • সার্ভার নিজেই ক্লায়েন্টকে ডেটা পুশ করতে পারে।
  • মাত্র কয়েক বাইট (Bytes) ওভারহেড থাকে।
  • Sub-millisecond রিয়েল-টাইম লেটেন্সি।

2. Scaling Sockets with Redis Pub/Sub

The Multi-Server Dilemma

যখন আপনার অ্যাপে লাখ লাখ ইউজার আসবে, তখন একটি Node.js সার্ভার দিয়ে কাজ হবে না। আপনি Load Balancer দিয়ে ৩টি সার্ভার বানালেন। সমস্যা হলো— Socket.io মেমোরিতে (RAM) কানেকশন সেভ রাখে। ইউজার "A" কানেক্ট হলো সার্ভার-১ এ, আর ইউজার "B" কানেক্ট হলো সার্ভার-২ এ। এখন "A" মেসেজ পাঠালে "B" সেটি পাবে না!

The Pro Solution: আমরা Redis Adapter (Pub/Sub) ব্যবহার করবো। কোনো সার্ভারে মেসেজ আসলেই সে সেটি Redis এ ব্রডকাস্ট (Publish) করে দিবে। বাকি সার্ভারগুলো সেটি শুনে (Subscribe) তাদের ক্লায়েন্টদের পাঠিয়ে দিবে।

server.js (Scaling Sockets)
const { Server } = require('socket.io');
const { createAdapter } = require('@socket.io/redis-adapter');
const { createClient } = require('redis');

// 1. Create Redis Pub/Sub Clients
const pubClient = createClient({ url: 'redis://localhost:6379' });
const subClient = pubClient.duplicate();

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
    
    const io = new Server(httpServer, {
        // 2. Attach Redis Adapter to Socket.io
        adapter: createAdapter(pubClient, subClient)
    });

    io.on('connection', (socket) => {
        socket.on('chat_message', (msg) => {
            // 3. This will now broadcast across ALL Node.js instances!
            io.emit('chat_message', msg); 
        });
    });
});

3. Network Architecture Simulator

HTTP Polling এবং WebSockets এর মধ্যে আন্ডার-দ্য-হুড (Under the hood) গতির পার্থক্য দেখতে নিচের টগল (Toggle) বাটনগুলো ব্যবহার করুন। মনে রাখবেন, WebSocket মোড অন না থাকলে নিচের লাইভ চ্যাট সিস্টেমটি কাজ করবে না!

Clients
Socket Server
[HTTP Polling] Connections closed after response. Real-time chat disabled.

4. Live Chat Application (Demo)

চলুন এবার একটি রিয়েল-টাইম চ্যাট ইন্টারফেস দেখি। আপনি Client-A (Faravi) থেকে কোনো মেসেজ টাইপ করে সেন্ড করলে, সেটি Client-B এর স্ক্রিনে রিয়েল-টাইমে ব্রডকাস্ট হবে এবং উল্টোটাও কাজ করবে!

Client A (Faravi)

Disconnected
System Welcome to the WebSocket Room.
Client B is typing...

Client B (Guest)

Disconnected
System Welcome to the WebSocket Room.
Client A is typing...