Socket.IO Acknowledgements and Timeouts
ack callback, timeout সহ emit, error handling ও delivery confirmation — বাংলায়।
সাধারণ emit-এ আপনি জানেন না receiver message পেল কিনা। Acknowledgement (ack) হলো সেই স্বীকৃতি — receiver কাজ শেষ করে callback-এ উত্তর দেয়।
শেখার লক্ষ্য
- server → client ও client → server ack পাঠানো
socket.timeout()দিয়ে নির্দিষ্ট সময়ে উত্তর না পেলে handle করা- ack-এর ভুল ও error ধরা
Server → Client Acknowledgement
Client emit করার সময় শেষ argument-এ একটি callback দেয়; server সেটি ack param হিসেবে পায় এবং কাজ শেষে কল করে।
// client
socket.emit("order:create", { item: "আম", qty: 2 }, (response) => {
if (response.success) {
console.log("Order id:", response.orderId);
} else {
console.error("ব্যর্থ:", response.message);
}
});// server
io.on("connection", (socket) => {
socket.on("order:create", (payload, ack) => {
// ack একটি function — শেষে কল করতে হবে
if (!payload || !payload.item) {
ack({ success: false, message: "item প্রয়োজন" });
return;
}
const orderId = "ORD-" + Date.now();
ack({ success: true, orderId });
});
});Line-by-line:
- Client emit-এর শেষ param
(response) => {...}— এটিই ack callback - Server handler শেষ param
ack— কল করলে client-এর callback চালু হয় ack({...})— একবারই কল করুন; কখনো দুইবার নয়
Server-এ ack কল না করলে client-এর callback কখনো চলে না এবং memory leak-এর ঝুঁকি তৈরি হয়। প্রতিটি code path-এ ঠিক একবার ack কল করুন — error path-এও।
Client → Server Acknowledgement
উল্টো দিকেও সম্ভব — server emit করে callback পায়, client ack param নিয়ে উত্তর দেয়।
// server
io.to(socket.id)
.timeout(5000)
.emit("client:ping", { at: Date.now() }, (err, responses) => {
if (err) {
// ৫ সেকেন্ডে কেউ উত্তর দেয়নি
console.log("timeout বা error:", err);
return;
}
console.log("client বলল:", responses[0]);
});// client
socket.on("client:ping", (payload, ack) => {
// কাজ শেষে উত্তর
ack({ ok: true, receivedAt: payload.at });
});Timeout API
.timeout(ms) দিয়ে নির্দিষ্ট সময়ে উত্তর না এলে ack callback-এর প্রথম param-এ error আসে:
socket.timeout(3000).emit("image:process", url, (err, result) => {
if (err) {
console.log("উত্তর আসেনি, processing আটকে গেল");
return;
}
console.log("result:", result);
});socket.emit-এর আগে .timeout(ms) বসান। timeout কেবল ack-এর জন্য প্রযোজ্য (event নিজে cancel হয় না)। .timeout() সেট করার পর নির্ধারিত সময়ে অপরপ্রান্ত থেকে উত্তর না এলে callback-এর প্রথম param-এ err আসে।
Broadcast + Ack (v4)
io.to(room).emit(...)-এ ack দিলে একাধিক client-এর উত্তর array হিসেবে আসে:
io.to("general")
.timeout(4000)
.emit("vote:ask", { id: 1 }, (err, responses) => {
if (err) return;
// responses = [{ id, choice }, ...]
const yes = responses.filter((r) => r.choice === "yes").length;
console.log("yes ভোট:", yes);
});room-এর সবাইকে একই সাথে অনুরোধ পাঠিয়ে সব উত্তর একত্রে পাওয়া — ভোট, নিলাম, live সমীক্ষা, দ্রুত consensus-এর জন্য দারুণ। শুধু মনে রাখুন: উত্তর যেমন সময়মতো আসে, তেমনি কেউ না দিলেও timeout-এ situation handle করতে হবে।
Real-World Use Cases
- Order confirmation — server order create করেছে কিনা client নিশ্চিত হয়
- Form/validation response — submit-এর ফলাফল
- Media process — image/video process শেষের signal
- Vote/poll — room-এর সব উত্তর সংগ্রহ
- Delivery receipt — message সব device-এ পৌঁছেছে কিনা
সাধারণ ভুল ও সমাধান
- ack ভুলে যাওয়া — server-এ
ack(...)না ডাকলে client আটকে থাকে - দুইবার ack — same handler-এ দুবার কল করলে error; একবারই
- timeout না দেওয়া — production-এ নির্দিষ্ট millisecond timeout দিন
Practice Task
order:create-এর মতো একটি event বানিয়ে success/error দুই পথেই ack দিন.timeout(2000)দিয়ে একটি slow handler test করুন — timeout error handle করুন- একটি room-এর সবাইকে vote করতে বলুন ও ফলাফল aggregate করুন
সম্পর্কিত অধ্যায়: Events · Sending and Receiving Data · Private and Group Messaging