Real-time App with WebSockets

React.js দিয়ে Real-time অ্যাপ (WebSockets) — সম্পূর্ণ গাইড (বাংলা)

Real-time অ্যাপ মানে হলো ব্যবহারকারীর ইন্টারঅ্যাকশন মুহুর্তেই (instant) অন্য ব্যবহারকারীদের কাছে দেখা বা পৌঁছানো — যেমন: চ্যাট অ্যাপ, লাইভ নোটিফিকেশন, রিয়েল-টাইম কোল্যাবরেশন, লাইভ স্পোর্টস স্কোর ইত্যাদি। এই ধরনের অ্যাপ্লিকেশন তৈরির জন্য সবচেয়ে জনপ্রিয় পদ্ধতি হলো WebSocket — যা সার্ভার ও ক্লায়েন্টের মধ্যে একটানা (full-duplex) সংযোগ রাখে এবং দুইদিকে ডাটা পাঠাতে দেয়।


এখানে আমরা কি শিখবো?

  • WebSocket কী ও কেন ব্যবহার করবেন
  • Socket.IO vs Native WebSocket — কখন কোনটি নির্বাচন করবেন
  • Node.js সার্ভার উদাহরণ (Socket.IO)
  • React ক্লায়েন্ট উদাহরণ (Socket.IO Client + Custom Hook)
  • Rooms, Broadcast, Presence (online users)
  • Reconnect, Error handling, Cleanup
  • Security, Scaling ও Deployment টিপস

WebSocket কি?

WebSocket হলো একটি network protocol (TCP উপর) যা ব্রাউজার ও সার্ভারের মধ্যে persistent connection তৈরি করে। HTTP এর মতো request-response ছাড়াও সার্ভার ইনিশিয়েটেবল মেসেজ পাঠাতে পারে। ফলে লেটেন্সি কমে এবং রিয়েল-টাইম ডাটা ট্রান্সফার সহজ হয়।


Socket.IO বনাম Native WebSocket

বৈশিষ্ট্য Socket.IO WebSocket (native)
Ease of use সহজ — auto-reconnect, events, rooms কম্প্যাক্ট — low-level API
Fallback (old browsers) আছে (transport fallback) না
Binary support আছে আছে
Scaling কিছু অতিরিক্ত config প্রয়োজন (adapter) প্রত্যেক ক্ষেত্রে কাস্টম্ কনফিগ দরকার
Recommendation General apps, quick dev → Socket.IO Low-level control চান → native WebSocket

প্র্যাকটিক্যাল উদাহরণ — Socket.IO ব্যবহার করে

১) সার্ভার (Node.js + Express + Socket.IO)

// server/index.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, {
  cors: { origin: "http://localhost:3000", credentials: true }
});

// Simple connection handler
io.on("connection", (socket) => {
  console.log("User connected:", socket.id);

  // Join a room
  socket.on("joinRoom", (room) => {
    socket.join(room);
    io.to(room).emit("systemMessage", `${socket.id} joined ${room}`);
  });

  // Handle chat message and broadcast to room
  socket.on("sendMessage", ({ room, message, user }) => {
    const payload = { user, message, time: Date.now() };
    io.to(room).emit("newMessage", payload);
  });

  // Presence: notify others when disconnecting
  socket.on("disconnect", (reason) => {
    console.log("Disconnected:", socket.id, reason);
  });
});

server.listen(5000, () => console.log("Server running on 5000"));

এই সার্ভারঃ

  • কানেকশনের সময় socket.id দেখায়
  • rooms এ join করে broadcast করে
  • sendMessage ইভেন্ট হ্যান্ডেল করে room-এ পাঠায়

২) React ক্লায়েন্ট (Socket.IO Client + Custom Hook)

প্রথমে dependency ইনস্টল করুন:

npm install socket.io-client
// src/hooks/useSocket.js
import { useEffect, useRef, useState } from "react";
import { io } from "socket.io-client";

export default function useSocket(serverUrl, options = {}) {
  const socketRef = useRef(null);
  const [connected, setConnected] = useState(false);
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    // Create socket
    socketRef.current = io(serverUrl, {
      withCredentials: true,
      ...options
    });

    const socket = socketRef.current;

    socket.on("connect", () => {
      setConnected(true);
      console.log("Connected:", socket.id);
    });

    socket.on("disconnect", () => {
      setConnected(false);
      console.log("Disconnected");
    });

    socket.on("newMessage", (msg) => {
      setMessages((prev) => [...prev, msg]);
    });

    // error handling
    socket.on("connect_error", (err) => {
      console.error("Socket connect_error:", err);
    });

    // cleanup on unmount
    return () => {
      if (socket) {
        socket.disconnect();
      }
    };
  }, [serverUrl]);

  const sendMessage = (room, message, user) => {
    socketRef.current?.emit("sendMessage", { room, message, user });
  };

  const joinRoom = (room) => {
    socketRef.current?.emit("joinRoom", room);
  };

  return { connected, messages, sendMessage, joinRoom };
}
// src/components/Chat.jsx
import React, { useState } from "react";
import useSocket from "../hooks/useSocket";

export default function Chat() {
  const { connected, messages, sendMessage, joinRoom } = useSocket("http://localhost:5000");
  const [room, setRoom] = useState("global");
  const [text, setText] = useState("");

  const handleJoin = () => joinRoom(room);

  const handleSend = () => {
    if (!text) return;
    sendMessage(room, text, "User1");
    setText("");
  };

  return (
     <div>
<h2>Chat (connected: {connected ? "Yes" : "No"})</h2>

<div>
<input value={room} onChange={(e) => setRoom(e.target.value)} />
<button onClick={handleJoin}>Join Room</button>
</div>

<div style={{height:200, overflow:'auto', border:'1px solid #ccc', marginTop:10}}>
{messages.map((m,i) => (
<div key={i}><strong>{m.user}:</strong> {m.message}</div>
))}
</div>

<div style={{marginTop:10}}>
<input value={text} onChange={(e) => setText(e.target.value)} />
<button onClick={handleSend}>Send</button>
</div>
</div> ); }

Rooms, Broadcast & Presence

  • Rooms: Socket.IO এর room সুবিধা ব্যবহার করে আপনি channel/room বানাতে পারেন — যেমন chat room, game room।
  • Broadcast: io.to(room).emit(...) দিয়ে নির্দিষ্ট room-এ broadcast করতে পারেন।
  • Presence: online user tracking করার জন্য server-side একটি map রাখুন: socketId → userInfo এবং connect/disconnect ইভেন্ট হ্যান্ডেল করুন।

Reconnect, Error Handling ও Cleanup

  • Socket.IO auto-reconnect দেয় (configurable)।
  • connect_error ইভেন্ট লিসেন করুন এবং উপযুক্ত UI দেখান (retry, offline indicator)।
  • Component unmount হলে সব listener remove করে socket.disconnect() করুন—বি.দ্র. না করলে মেমরি লিক হবে।

Security Considerations

  • Authentication: WebSocket কানেকশনে token পাঠান (initial handshake headers বা query) এবং সার্ভারে verify করুন।
  • Use HTTPS / WSS (secure websocket) in production.
  • Rate limiting: flooding প্রতিরোধের জন্য rate-limit logic বা message throttling লাগাতে হবে।
  • Validate incoming data on server — কখনও ক্লায়েন্ট থেকে trust করবেন না।
  • Use CORS এবং origins whitelist করুন।

Scaling & Deployment

একটি সহজ single-server Socket.IO অ্যাপ ছোট প্রোজেক্টের জন্য ঠিক আছে, কিন্তু বড় অ্যাপে scaling লাগলে:

  • Use a message broker (Redis) — Socket.IO adapter (socket.io-redis) দিয়ে multiple node instances মধ্যে events share করা যায়।
  • Deploy behind a load balancer that supports sticky sessions / or use Redis adapter to share socket state.
  • Consider managed services: Pusher, Ably, Firebase Realtime / Firestore for simpler scaling (paid).

Performance Tips

  • Send minimal payloads (avoid sending large objects frequently).
  • Use binary data for heavy transfers (when needed).
  • Batch frequent updates (debounce/throttle).
  • Avoid re-rendering whole React tree on every message — only update relevant components (use state slices, memoization).

Alternatives to WebSockets

  • Server-Sent Events (SSE): server→client stream-only, simpler for one-way updates.
  • WebRTC: peer-to-peer real-time media/data (for video/audio/file transfer).
  • Long-polling / HTTP2 push: legacy or special cases.

Testing & Debugging

  • Use browser devtools network tab → WS frames view to inspect messages.
  • Log socket events on server and client (with levels) for debugging.
  • Write integration tests for critical flows (connect, join room, send/receive, disconnect).

উপসংহার (Summary)

Real-time অ্যাপ বানাতে WebSockets (অথবা Socket.IO) খুবই কার্যকর। React ক্লায়েন্টে Custom Hook বানিয়ে socket logic আলাদা রাখলে কোড পরিচ্ছন্ন ও reusable হয়। সার্ভার-সাইডে security, validation ও scaling নিয়ে সতর্ক থাকতে হবে। ছোট প্রোজেক্টে Socket.IO দ্রুত ডেভলপমেন্ট দেয়; বড় প্রোজেক্টে scaling জন্য Redis adapter বা managed services বিবেচনা করুন।

👼 Quiz
/

লোড হচ্ছে...

Interview Questions:

1. WebSocket কী?

WebSocket হলো একটি communication protocol যা client এবং server এর মধ্যে real-time, two-way communication নিশ্চিত করে।

2. WebSocket এবং HTTP এর মধ্যে পার্থক্য কী?

HTTP request-response ভিত্তিক, আর WebSocket একবার connection তৈরি হলে real-time ডাটা আদান-প্রদান করতে পারে।