July 23, 2026 · 5 min read
Webhook নাকি WebSocket? কোনটা কখন ব্যবহার করবেন ?
ডেভেলপার হিসেবে কাজ করতে গিয়ে একটা সমস্যায় বারবার পড়তে হয় — "কিছু একটা ঘটেছে" এই খবরটা এক সিস্টেম থেকে আরেক সিস্টেমে পৌঁছাবে কীভাবে?
পেমেন্ট সফল হয়েছে, নতুন মেসেজ এসেছে, ডেলিভারি ম্যান লোকেশন বদলেছে, কেউ অর্ডার দিয়েছে — এসব খবর কে কাকে জানাবে?
সবচেয়ে সহজ উত্তর হলো: ক্লায়েন্ট বারবার জিজ্ঞেস করবে। এটাকে বলে polling। প্রতি ৫ সেকেন্ডে একটা API কল — "নতুন কিছু আছে?" ৯৯ বার উত্তর আসবে "নাই", ১ বার আসবে "আছে"। কাজ চলে যায়, কিন্তু সার্ভারের উপর অহেতুক চাপ পড়ে আর ইউজার আপডেট পায় দেরিতে।
এই সমস্যার দুটো ভালো সমাধান আছে — Webhook আর WebSocket। নাম প্রায় একরকম হলেও দুটো সম্পূর্ণ আলাদা জিনিস, আলাদা কাজের জন্য।
Webhook কী?
Webhook হলো উল্টো দিকের API।
সাধারণ API-তে আপনি অন্যের সার্ভারে রিকোয়েস্ট পাঠান। Webhook-এ ঘটনা ঘটলে অন্যের সার্ভার আপনার সার্ভারে রিকোয়েস্ট পাঠায়। এজন্য একে "reverse API" বা "HTTP callback"-ও বলা হয়।
আপনি একবার তাদের ড্যাশবোর্ডে আপনার URL দিয়ে রাখবেন — যেমন https://api.myapp.com/webhooks/payment। এরপর যখনই সংশ্লিষ্ট event ঘটবে, তারা ওই URL-এ একটা HTTP POST পাঠিয়ে দেবে
১. আপনি Provider-এর কাছে আপনার callback URL রেজিস্টার করেন ২. তাদের সিস্টেমে event ঘটে (যেমন পেমেন্ট সফল) ৩. তারা আপনার URL-এ JSON payload সহ POST করে, সাথে একটা signature header ৪. আপনি signature যাচাই করে 200 OK ফেরত দেন ৫. আপনি 200 না দিলে তারা কিছুক্ষণ পর আবার চেষ্টা করে (retry)
বাস্তব উদাহরণ
bKash / SSLCommerz / Nagad — পেমেন্ট সফল হলে IPN/callback আসে
GitHub — কেউ push করলে বা PR খুললে আপনার CI সার্ভারে হিট করে
Stripe — subscription renew, refund, charge failed
Twilio / SMS gateway — মেসেজ ডেলিভার হলো কিনা
NestJS-এ একটা webhook endpoint
@Controller('webhooks')
export class WebhookController {
constructor(private readonly queue: PaymentQueue) {}
@Post('payment')
@HttpCode(200)
async handle(
@Req() req: RawBodyRequest<Request>,
@Headers('x-signature') signature: string,
) {
// ১. Signature যাচাই — এটা বাদ দেওয়া যাবে না
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.rawBody)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
throw new UnauthorizedException();
}
// ২. ভারী কাজ queue-তে পাঠান, এখানে করবেন না
await this.queue.add('process-payment', req.body);
// ৩. দ্রুত 200 ফেরত দিন
return { received: true };
}
}
Webhook ব্যবহারে যে ভুলগুলো সবচেয়ে বেশি হয়
Signature যাচাই না করা। আপনার webhook URL পাবলিক। যে কেউ ওখানে ভুয়া "payment success" পাঠিয়ে দিতে পারে। HMAC signature যাচাই করা বাধ্যতামূলক।
Idempotency না রাখা। একই webhook দুইবার আসতে পারে — নেটওয়ার্ক সমস্যায় আপনার 200 তাদের কাছে পৌঁছায়নি, তাই তারা আবার পাঠিয়েছে। event_id ডাটাবেজে unique করে রাখুন, একই id দ্বিতীয়বার এলে চুপচাপ 200 দিয়ে দিন। নাহলে একই পেমেন্টে দুইবার ব্যালান্স যোগ হয়ে যাবে।
Response-এর ভেতরে ভারী কাজ করা। ইমেইল পাঠানো, PDF বানানো, তৃতীয় কোনো API কল — এসব করতে গিয়ে দেরি হলে Provider timeout ধরে retry করবে। কাজটা BullMQ বা অন্য কোনো queue-তে ফেলে দিয়ে সাথে সাথে 200 দিন।
লোকাল টেস্টিং। localhost-এ webhook আসবে না। ডেভেলপমেন্টের সময় ngrok বা Cloudflare Tunnel ব্যবহার করুন।
WebSocket কী?
WebSocket একটা স্থায়ী, দুই দিকের কানেকশন।
সাধারণ HTTP-তে প্রতিটা রিকোয়েস্ট আলাদা — কথা বলে ফোন রেখে দেওয়ার মতো। WebSocket-এ একবার লাইন কানেক্ট হলে সেটা খোলা থাকে; দুই পক্ষই যখন খুশি কথা বলতে পারে।
শুরুটা হয় সাধারণ HTTP রিকোয়েস্ট দিয়েই, কিন্তু তাতে একটা বিশেষ হেডার থাকে — Upgrade: websocket। সার্ভার রাজি থাকলে 101 Switching Protocols ফেরত দেয়, আর তখনই HTTP কানেকশনটা WebSocket কানেকশনে বদলে যায়।
এরপর থেকে আর রিকোয়েস্ট-রেসপন্স নেই। শুধু frame — ছোট ছোট ডেটার প্যাকেট, দুই দিকেই চলাচল করে। মাঝে মাঝে ping/pong যায় কানেকশন বেঁচে আছে কিনা দেখতে।
বাস্তব উদাহরণ
চ্যাট অ্যাপ — মেসেজ, typing indicator, online status
রাইড শেয়ারিং / ফুড ডেলিভারিতে লাইভ লোকেশন
লাইভ ড্যাশবোর্ড, স্টক প্রাইস, লাইভ স্কোর
Collaborative editing (একসাথে কয়েকজন একই ডকুমেন্ট এডিট)
মাল্টিপ্লেয়ার গেম
NestJS Gateway দিয়ে সহজ উদাহরণ
@WebSocketGateway({ cors: true })
export class ChatGateway implements OnGatewayConnection {
@WebSocketServer() server: Server;
async handleConnection(client: Socket) {
// কানেকশনেই auth যাচাই করুন
const user = await this.auth.verify(client.handshake.auth.token);
if (!user) return client.disconnect();
client.data.userId = user.id;
client.join(user:${user.id});
}
@SubscribeMessage('message:send')
async onMessage(client: Socket, payload: SendMessageDto) {
const message = await this.chat.save(client.data.userId, payload);
// শুধু ওই রুমের সবাইকে পাঠান
this.server.to(room:${payload.roomId}).emit('message:new', message);
}
}
WebSocket ব্যবহারে যেসব জায়গায় আটকাবেন
Scaling। দুইটা সার্ভার ইনস্ট্যান্স থাকলে সমস্যা শুরু। User A কানেক্টেড সার্ভার-১-এ, User B সার্ভার-২-এ। সার্ভার-১ থেকে broadcast করলে B পাবে না। সমাধান — Redis adapter (@socket.io/redis-adapter), যাতে সব ইনস্ট্যান্স একে অপরকে ইভেন্ট জানাতে পারে। সাথে load balancer-এ sticky session চালু রাখতে হবে।
Reconnection। মোবাইল ইউজারের নেট যাবে-আসবে। কানেকশন ছিঁড়ে গেলে অটো-রিকানেক্ট এবং যে মেসেজগুলো মিস হয়েছে সেগুলো fetch করার লজিক দরকার। শুধু WebSocket-এর উপর ভরসা করে মেসেজ স্টেট রাখবেন না — ডাটাবেজই source of truth।
Nginx/proxy কনফিগ। VPS-এ deploy করলে Nginx-এ Upgrade আর Connection হেডার forward করতে হবে, নাহলে handshake ফেল করবে:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
অ্যাপ ব্যাকগ্রাউন্ডে গেলে। মোবাইল OS ব্যাকগ্রাউন্ডে সকেট কানেকশন কেটে দেয়। তাই অ্যাপ বন্ধ থাকা অবস্থায় notification পাঠাতে WebSocket নয়, FCM push notification লাগবে।
তাহলে কখন কোনটা?
সিদ্ধান্তটা আসলে একটা প্রশ্নের উপর নির্ভর করে — কে কাকে জানাচ্ছে?
Webhook নিন যখন — তৃতীয় কোনো সার্ভিসের ঘটনা আপনার সার্ভারকে জানাতে হবে। পেমেন্ট কনফার্মেশন, CI/CD ট্রিগার, SMS ডেলিভারি রিপোর্ট, ইনভেন্টরি সিঙ্ক। কয়েক সেকেন্ড দেরি হলে সমস্যা নেই, কিন্তু খবরটা হারিয়ে গেলে সমস্যা।
WebSocket নিন যখন — ইউজার স্ক্রিনে তাকিয়ে আছে আর সাথে সাথে আপডেট দেখতে চায়। চ্যাট, লাইভ লোকেশন, নোটিফিকেশন ব্যাজ, লাইভ ড্যাশবোর্ড।
দুইটাই একসাথে — বাস্তব প্রজেক্টে এটাই সবচেয়ে বেশি হয়। একটা ই-কমার্স অ্যাপ ভাবুন: পেমেন্ট গেটওয়ে webhook পাঠিয়ে আপনার সার্ভারকে জানাল পেমেন্ট সফল; আপনার সার্ভার সাথে সাথে WebSocket দিয়ে ইউজারের স্ক্রিনে অর্ডার স্ট্যাটাস "Confirmed" করে দিল। দুটো একে অপরের প্রতিদ্বন্দ্বী নয়, একই চেইনের দুটো অংশ।
আরও দুটো বিকল্প মনে রাখুন
সব real-time কাজে WebSocket লাগে না।
SSE (Server-Sent Events) — শুধু সার্ভার থেকে ক্লায়েন্টে ডেটা পাঠাতে হলে এটাই যথেষ্ট। সাধারণ HTTP-র উপর চলে, অটো-রিকানেক্ট বিল্ট-ইন, setup অনেক সহজ। লাইভ নোটিফিকেশন ফিড বা AI response streaming-এর জন্য চমৎকার।
Push Notification (FCM/APNs) — অ্যাপ বন্ধ থাকলে ইউজারকে জানানোর একমাত্র উপায়।
Conclusion:
সহজভাবে মনে রাখুন —
Webhook হলো চিঠি — কিছু ঘটলে একবার পাঠানো হয়, পৌঁছেছে কিনা নিশ্চিত করা হয়। WebSocket হলো ফোন কল — লাইন খোলা থাকে, দুজনই যখন খুশি কথা বলতে পারে।
আপনার ফিচারটার জন্য কোনটা দরকার, সেটা ঠিক করার আগে নিজেকে জিজ্ঞেস করুন: খবরটা কি এক সিস্টেম থেকে আরেক সিস্টেমে যাচ্ছে, নাকি সরাসরি ইউজারের স্ক্রিনে? উত্তরটা পেলেই টুল বাছাই সহজ হয়ে যাবে।
1 likes
Anyone can like this article.
Comments are disabled for this article.