Long Polling تکنیکی برای تعامل کلاینت و سرور است که در آن سرور درخواست HTTP را تا زمان ظهور دادههای جدید یا انقضای مهلت زمانی باز نگه میدارد. برخلاف پرسوجوی دورهای، سرور بلافاصله پاسخ خالی را برنمیگرداند، بلکه منتظر وقوع رویداد برای ارسال داده به کلاینت میماند. به گفته MDN Web Docs، 2024، Long Polling یک راهحل پرتقاضا برای برنامههای بلادرنگ باقی میماند، جایی که WebSocket در دسترس نیست یا اضافی است.
نکات اصلی
Long Polling الگویی از تعامل در معماری کلاینت-سرور است که در آن کلاینت یک درخواست HTTP را آغاز میکند و سرور ارسال پاسخ را تا زمانی که دادههای جدید ظاهر شوند یا مهلت زمانی مشخصی منقضی شود به تأخیر میاندازد. پس از دریافت پاسخ، کلاینت بلافاصله درخواست بعدی را ارسال میکند و اثر اتصال پیوسته را ایجاد میکند.
تکنیک Long Polling به عنوان تکاملیافته Short Polling برای کاهش تعداد درخواستهای خالی HTTP پدید آمد. در پرسوجوی سنتی، کلاینت هر N ثانیه یک بار درخواست ارسال میکند و سرور حتی در صورت نبود داده جدید پاسخ میدهد. در Long Polling، سرور از مکانیزم نگهداشتن اتصال استفاده میکند که حجم ترافیک بیهوده را به طور چشمگیری کاهش میدهد.
پیش از ظهور WebSocket در سال 2011، Long Polling روش اصلی سازماندهی بلادرنگ در وب بود. شرکتهایی مانند Facebook و Gmail از این تکنیک برای چتها و اعلانهای خود در اوایل دهه 2010 استفاده میکردند. بر اساس تحقیقات High Performance Browser Networking (Grigorik، 2013)، Long Polling تا 95٪ از تمام اتصالات بلادرنگ را در برنامههای وب بزرگ آن دوره پردازش میکرد.
کلاینت یک درخواست HTTP استاندارد به سرور ارسال میکند. سرور پس از دریافت درخواست، بلافاصله پاسخ را برنمیگرداند — آن را در صف انتظار قرار میدهد. هنگامی که رویدادی در سرور رخ میدهد (پیام جدید، تغییر داده)، سرور پاسخ را تشکیل داده و به کلاینت ارسال میکند. کلاینت پس از دریافت پاسخ، بلافاصله یک درخواست Long Polling جدید ایجاد میکند و چرخه تکرار میشود.
Long Polling بر اساس دنباله مراحل زیر کار میکند. کلاینت یک درخواست HTTP GET به endpoint سرور ارسال میکند. سرور پس از دریافت درخواست، وجود دادههای جدید را در صف رویداد بررسی میکند. اگر دادهای وجود نداشته باشد، سرور درخواست را در حالت انتظار نگه میدارد و فوراً پاسخ نمیدهد. مکانیزم نگهداشتن به پیادهسازی سرور بستگی دارد — اغلب از پردازش ناهمگام با callback یا معماری رویدادمحور استفاده میشود.
هنگامی که رویدادی در سمت سرور رخ میدهد (مثلاً کاربر پیامی در چت ارسال کرد)، سرور یک پاسخ HTTP با بدنه حاوی آن دادهها تشکیل میدهد و اتصال را پایان میدهد. کلاینت پاسخ را دریافت میکند، دادهها را پردازش میکند و بلافاصله یک درخواست جدید آغاز میکند. اگر در طول انتظار دادهای ظاهر نشود، سرور پس از انقضای مهلت زمانی یک پاسخ خالی ارسال میکند و کلاینت نیز اتصال را دوباره ایجاد میکند. Timeout معمولاً 30–60 ثانیه برای تعادل بین بار و تأخیر است.
پارامتر کلیدی پیکربندی Long Polling مهلت زمانی انتظار است. مهلت زمانی خیلی کوتاه (کمتر از 10 ثانیه) منجر به افزایش تعداد درخواستها میشود و تکنیک را به Short Polling نزدیک میکند. مهلت زمانی خیلی طولانی (بیش از 120 ثانیه) میتواند باعث قطع اتصال توسط پروکسیهای میانی و بالانسرهای بار شود. مقدار توصیهشده برای اکثر سناریوها 30–45 ثانیه است.
اگر در طول یک درخواست Long Polling چندین رویداد در سرور رخ دهد، سرور باید همه آنها را در یک پاسخ منتقل کند یا یک صف رویداد در سمت کلاینت سازماندهی کند. برای این کار از بافر کردن رویداد استفاده میشود: سرور رویدادهایی را که در طول نگهداشتن درخواست رخ دادهاند جمعآوری کرده و به عنوان آرایهای از دادهها در بدنه پاسخ منتقل میکند.
بیایید یک پیادهسازی ساده Long Polling در سمت کلاینت با استفاده از Fetch API مدرن را بررسی کنیم. تابع کلاینت درخواست ارسال میکند و پس از دریافت پاسخ، خود را به صورت بازگشتی فراخوانی میکند.
async function longPoll(url) {
try {
const response = await fetch(url);
const data = await response.json();
handleData(data);
longPoll(url);
} catch (error) {
console.error("خطای Long Polling", error);
setTimeout(() => longPoll(url), 3000);
}
}
function handleData(data) {
if (data.events && data.events.length > 0) {
data.events.forEach(event => {
console.log("رویداد جدید:", event);
});
}
}
longPoll("/api/events");
این کد یک حلقه بیپایان Long Polling ایجاد میکند: پس از دریافت پاسخ، تابع بلافاصله یک درخواست جدید ارسال میکند. در صورت خطای اتصال، یک تأخیر سه ثانیهای قبل از تلاش مجدد تنظیم میشود تا از بار بهمنی روی سرور جلوگیری شود.
در سمت سرور، باید درخواست را تا ظهور رویداد یا انقضای مهلت زمانی نگه داشت. نمونه پیادهسازی با استفاده از EventEmitter در Node.js این مکانیزم را نشان میدهد.
const express = require("express");
const EventEmitter = require("events");
const app = express();
const eventBus = new EventEmitter();
app.get("/api/events", (req, res) => {
const timeout = setTimeout(() => {
res.json({ events: [] });
}, 30000);
eventBus.once("new-event", (data) => {
clearTimeout(timeout);
res.json({ events: [data] });
});
});
app.post("/api/events", (req, res) => {
eventBus.emit("new-event", req.body);
res.send({ status: "ok" });
});
app.listen(3000);
بخش سرور از EventEmitter برای اطلاعرسانی به اتصالات Long Polling در انتظار هنگام ظهور دادههای جدید استفاده میکند. پس از رسیدن به مهلت زمانی 30 ثانیه، سرور یک آرایه خالی از رویدادها برمیگرداند و کلاینت یک درخواست جدید ایجاد میکند.
Long Polling در سناریوهایی استفاده میشود که نیاز به تحویل دادهها به صورت بلادرنگ دارند، اما استفاده از WebSocket به دلایل فنی یا زیرساختی ممکن نیست. رایجترین موارد — پروکسیهای شرکتی و فایروالهایی که اتصالات WebSocket را مسدود میکنند، و همچنین محیطهایی با پشتیبانی محدود از پروتکل در سمت سرور.
عامل کلیدی انتخاب Long Polling سازگاری معکوس است. همه کلاینتها و سرورهای HTTP از این روش پشتیبانی میکنند، که آن را به یک راهحل جهانی برای بلادرنگ بدون وابستگیهای اضافی تبدیل میکند. بر اساس HTTP Archive (2024)، حدود ۸٪ از تمام وبسایتها همچنان از Long Polling برای عملکرد پایه بلادرنگ استفاده میکنند.
Long Polling و Short Polling یک وظیفه را حل میکنند — تحویل داده از سرور به کلاینت — اما از نظر مکانیزم و کارایی تفاوت اساسی دارند. Short Polling از یک بازه پرسوجوی ثابت استفاده میکند، که در آن کلاینت درخواستهای HTTP را در فواصل زمانی مساوی بدون توجه به ظهور دادههای جدید روی سرور ارسال میکند.
| ویژگی | Long Polling | Short Polling |
|---|---|---|
| آغاز پاسخ | سرور داده را هنگام رویداد ارسال میکند | سرور به هر درخواست کلاینت پاسخ میدهد |
| تأخیر تحویل | حداقل، تا ۱ ثانیه | وابسته به بازه پرسوجو، ۳–۶۰ ثانیه |
| تعداد درخواستها | ۱ درخواست به ازای هر رویداد یا مهلت زمانی | N درخواست در واحد زمان (ثابت) |
| ترافیک در زمان بیکاری | کم (یک درخواست باز) | زیاد (درخواستها هر N ثانیه) |
| بار روی سرور | نگهداشتن اتصالات | پردازش درخواستهای مکرر |
| پیچیدگی پیادهسازی | متوسط (پردازش ناهمگام) | کم (درخواستهای HTTP معمولی) |
Short Polling در پیادهسازی سادهتر است، اما با همان فرکانس بهروزرسانی داده، بار قابل توجهی بیشتری روی سرور و شبکه ایجاد میکند. اگر تأخیر کمتر از ۵ ثانیه مورد نیاز باشد، Short Polling دهها درخواست در دقیقه تولید میکند، در حالی که Long Polling از یک درخواست به ازای هر رویداد یا مهلت زمانی استفاده میکند. برای برنامههایی با رویدادهای نادر، Long Polling از نظر ترافیک به مراتب کارآمدتر است.
WebSocket یک پروتکل بلادرنگ دوطرفه کامل است که پس از دستدهی اولیه HTTP روی TCP کار میکند. برخلاف Long Polling، WebSocket یک اتصال ثابت برقرار میکند و به سرور اجازه میدهد در هر لحظه بدون ایجاد یک درخواست HTTP جدید، داده را به کلاینت ارسال کند.
انتخاب بین Long Polling و WebSocket به چند عامل بستگی دارد. سازگاری: Long Polling از طریق هر پروکسی و فایروالی کار میکند، WebSocket ممکن است توسط شبکههای شرکتی مسدود شود. عملکرد: WebSocket سربار کمتری دارد (۲ بایت به ازای هر فریم در مقایسه با هدرهای کامل HTTP)، که در فرکانس بالای پیامها حیاتی است. مقیاسپذیری: Long Polling به دلیل نگهداشتن اتصالات متعدد به منابع بیشتری در سمت سرور نیاز دارد، WebSocket از یک اتصال ثابت به ازای هر جلسه استفاده میکند.
به گفته Mozilla Developer Network (2024)، WebSocket توسط همه مرورگرهای مدرن از نسخههای ۲۰۱۱–۲۰۱۵ پشتیبانی میشود، اما پروکسیهای شرکتی (مانند Symantec Blue Coat) همچنان آن را در ۱۵–۲۰٪ از شبکههای سازمانی مسدود میکنند که ارتباط Long Polling را به عنوان یک راهحل fallback حفظ میکند.
سؤالات متداول
Long Polling زمانی است که کلاینت از سرور میخواهد «وقتی دادههای جدید ظاهر شد پاسخ بده» و سرور اتصال را باز نگه میدارد و منتظر رویداد میماند. به محض ظاهر شدن داده، سرور پاسخ میدهد و کلاینت بلافاصله همان سؤال را دوباره میپرسد.
در Short Polling، کلاینت هر N ثانیه از سرور میپرسد که آیا داده وجود دارد، حتی اگر دادهای نباشد. در Long Polling، کلاینت یک بار میپرسد و سرور فقط زمانی پاسخ میدهد که داده واقعاً ظاهر شود. Long Polling درخواستهای خالی کمتری ایجاد میکند و بار شبکه را کاهش میدهد.
زمانی که WebSocket در دسترس نیست از Long Polling استفاده کنید: در شبکههای شرکتی که پروتکلهای غیر-HTTP را مسدود میکنند، در صورت نیاز به سازگاری معکوس با مرورگرهای قدیمی یا محدودیتهای سمت هاستینگ. WebSocket برای تبادل داده با فرکانس بالا کارآمدتر است.
مهلت زمانی Long Polling توصیهشده ۳۰–۴۵ ثانیه است. مقدار کمتر (۱۰–۱۵ ثانیه) تعداد درخواستها را افزایش میدهد، مقدار بیشتر (۶۰+ ثانیه) به دلیل قطع اتصال توسط بالانسرهای میانی خطرناک است. مقدار مهلت زمانی به معماری شبکه و الزامات تأخیر بستگی دارد.
معایب اصلی Long Polling — مصرف بالای حافظه روی سرور هنگام نگهداشتن هزاران اتصال، دشواری مقیاسدهی افقی (نیاز به صف رویداد متمرکز) و عدم وجود ارتباط دوطرفه واقعی — برای ارسال داده به سرور به درخواستهای POST جداگانه نیاز است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.