রহিম message পাঠাল —
করিম তাৎক্ষণিক দেখল!
HTTP-তে করিমকে বারবার জিজ্ঞেস করতে হতো "নতুন message এসেছে?"
Socket.IO-তে message
আসলে সরাসরি push হয় — poll করতে হয় না
HTTP vs WebSocket
4-Layer Security
Viewer Count
Token Bucket
Redis Adapter
Realtime System বুঝব আজকে
SLIDE 01
কেন HTTP যথেষ্ট না?
Realtime-এর জন্য HTTP-র সমস্যা
❌
HTTP Polling — রহিম প্রতি ২ সেকেন্ডে জিজ্ঞেস করছে "নতুন message এসেছে?"
HTTP সমস্যা
- প্রতিটা request নতুন connection
- Header বারবার পাঠাতে হয় (1KB+)
- ১০০০ user = ৫০০ request/sec
- Server ক্লান্ত, delay বেশি
// HTTP Polling — ভুল পদ্ধতি
setInterval(async () => {
const res = await fetch('/messages');
// নতুন message নেই? waste।
// আছে? তাহলে ঠিকাছে।
// কিন্তু ২ সেকেন্ড delay!
}, 2000);
✅
WebSocket — একবার connect করো, সারাক্ষণ open থাকে। Server যখন চাইলে push
করতে পারে।
WebSocket সুবিধা
- একটাই persistent connection
- Header overhead নেই (শুধু data)
- Server → Client push (real realtime)
- Latency: ১০০ms → ১ms
// Socket.IO — সঠিক পদ্ধতি
socket.on('new-message', (msg) => {
// Server push করলেই এসে যায়!
// Polling নেই, delay নেই
displayMessage(msg);
});
SLIDE 02
Socket System Architecture
পুরো system কীভাবে সাজানো
Client
Browser
⟷
Load
Balancer
→
Socket.IO
Server 1
⟷
Redis
Adapter
⟷
Socket.IO
Server 2
Namespace & Room
- Namespace: /live, /chat, /admin
- Room: লাইভ class-এর room = classId
- রহিম join করে room "class-101"
- করিম ও "class-101"-এ → দুজন দেখা যায়
// Server side
io.on('connection', (socket) => {
socket.on('join-class', (classId) => {
socket.join(`class:${classId}`);
// ঐ room-এ broadcast
io.to(`class:${classId}`).emit(
'user-joined',
{ name: socket.user.name }
);
});
});
Event Types
- join-class: room-এ যোগ দাও
- leave-class: room ছাড়ো
- send-message: message পাঠাও
- viewer-count: কতজন দেখছে
- typing: টাইপ করছে indicator
💡
Room মানে গ্রুপ। "class-101" room-এ যা emit করবে শুধু সেই room-এর সবাই পাবে।
SLIDE 03
Connection-এর আগে ৪ Layer Security
যে কেউ connect করতে পারবে না
১
JWT Verify — Handshake-এ token পাঠাতে হবে। Invalid token → connection reject।
২
Rate Limit — এক IP থেকে ৫ সেকেন্ডে ৩টার বেশি connect attempt → block করো।
৩
Enrollment Check — রহিম কি এই class-এ enrolled? না হলে room join করতে পারবে না।
৪
Ban Check — Redis-এ রহিম ban আছে? তাহলে connection-এই reject।
// Socket middleware (runs before connection)
io.use(async (socket, next) => {
// Layer 1: JWT
const token = socket.handshake.auth.token;
const user = jwt.verify(token, SECRET);
// Layer 2: Rate limit (Redis)
const key = `socket-connect:${socket.handshake.address}`;
const count = await redis.incr(key);
await redis.expire(key, 5);
if (count > 3) return next(new Error('Too many connections'));
// Layer 3: Enrollment (done in join-class event)
// Layer 4: Ban check
const banned = await redis.get(`banned:${user.id}`);
if (banned) return next(new Error('Banned'));
socket.user = user;
next();
});
SLIDE 04
Viewer Count Architecture
Live class-এ কতজন আছে — realtime
কীভাবে count রাখি?
- Redis SET: viewers:class-101 = {রহিম, করিম, জাবের}
- Join → SADD, Leave/Disconnect → SREM
- Count = SCARD (set size)
- Multiple server-এও accurate
socket.on('join-class', async (classId) => {
const roomKey = `viewers:${classId}`;