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 إلى نقطة نهاية الخادم. عند استلام الطلب، يتحقق الخادم من وجود بيانات جديدة في قائمة الأحداث. إذا لم تكن هناك بيانات، يحتفظ الخادم بالطلب في حالة انتظار، دون إرسال استجابة فورًا. تعتمد آلية الاحتفاظ على تنفيذ الخادم — غالبًا ما يتم استخدام المعالجة غير المتزامنة مع استدعاءات الإرجاع أو الهندسة القائمة على الأحداث.
عند حدوث حدث على جانب الخادم (على سبيل المثال، أرسل مستخدم رسالة في الدردشة)، يقوم الخادم بتكوين استجابة HTTP بمحتوى يحتوي على هذه البيانات وينهي الاتصال. يتلقى العميل الاستجابة، يعالج البيانات ويبدأ فورًا طلبًا جديدًا. إذا لم تظهر بيانات أثناء فترة الانتظار، يرسل الخادم استجابة فارغة بعد انتهاء الوقت المحدد، ويعيد العميل أيضًا إنشاء الاتصال. عادة ما يكون الوقت المحدد 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)، حوالي 8% من جميع مواقع الويب تستمر في استخدام Long Polling للوظائف الأساسية في الوقت الفعلي.
Long Polling و Short Polling يحلان نفس المشكلة — توصيل البيانات من الخادم إلى العميل — ولكنهما يختلفان جوهريًا في الآلية والكفاءة. يستخدم Short Polling فاخر استعلام ثابت حيث يرسل العميل طلبات HTTP على فواصل زمنية متساوية بغض النظر عن ظهور بيانات جديدة على الخادم.
| الخاصية | Long Polling | Short Polling |
|---|---|---|
| بدء الاستجابة | الخادم يرسل البيانات عند حدوث الحدث | الخادم يستجيب لكل طلب من العميل |
| زمن التوصيل | أدنى، حتى ثانية واحدة | يعتمد على فاخر الاستعلام، 3–60 ثانية |
| عدد الطلبات | طلب واحد لكل حدث أو وقت محدد | N طلب في وحدة الزمن (ثابت) |
| الحركة عند الخمول | منخفضة (طلب واحد مفتوح) | مرتفعة (طلبات كل N ثانية) |
| حمل الخادم | احتفاظ بالاتصالات | معالجة الطلبات المتكررة |
| تعقيد التنفيذ | متوسط (معالجة غير متزامنة) | منخفض (طلبات HTTP عادية) |
Short Polling أبسط في التنفيذ ولكنه يخلق حملًا أكبر بشكل ملحوظ على الخادم والشبكة بنفس تردد تحديث البيانات. إذا كان زمن الاستجابة أقل من 5 ثوانٍ مطلوبًا، فإن Short Polling يولّد عشرات الطلبات في الدقيقة، بينما Long Polling يستخدم طلبًا واحدًا لكل حدث أو وقت محدد. بالنسبة للتطبيقات ذات الأحداث نادرة، Long Polling أكثر كفاءة بمراتب من حيث حجم المرور.
WebSocket هو بروتوكول فوري كامل ثنائي الاتجاه يعمل فوق TCP بعد مصافحة HTTP أولية. على عكس Long Polling، ينشئ WebSocket اتصالاً واحدًا مستمرًا ويسمح للخادم بإرسال البيانات إلى العميل في أي وقت دون إنشاء طلب HTTP جديد.
يعتمد الاختيار بين Long Polling و WebSocket على عدة عوامل. التوافق: Long Polling يعمل من خلال أي وكيل وجدار حماية، بينما قد يكون WebSocket محجوبًا بواسطة الشبكات المؤسسية. الأداء: WebSocket له تكلفة إضافية أقل (2 بايت لكل إطار مقابل ترويسات HTTP كاملة)، وهذا حاسم عند تردد عالي للرسائل. قابلية التوسع: Long Polling يتطلب مزيدًا من الموارد على جانب الخادم بسبب احتفاظ عدد كبير من الاتصالات، بينما يستخدم WebSocket اتصالًا ثابتًا لكل جلسة.
وفقًا لـ Mozilla Developer Network (2024)، WebSocket مدعوم في جميع المتصفحات الحديثة منذ إصدارات 2011–2015، ولكن الوكلاء الميدانيين (على سبيل المثال Symantec Blue Coat) ما زالوا يحجبونه في 15–20% من الشبكات المؤسسية، مما يحافظ على أهمية Long Polling كحل احتياطي.
الأسئلة الشائعة
Long Polling هو عندما يطلب العميل من الخادم: «أجب عندما تصبح البيانات الجديدة متاحة»، ويحتفظ الخادم بالاتصال مفتوحًا في انتظار حدث. بمجرد ظهور البيانات، يستجيب الخادم، ويطرح العميل نفس السؤال مرة أخرى.
في Short Polling، يسأل العميل الخادم كل N ثانية عن وجود بيانات، حتى لو لم تكن موجودة. في Long Polling، يسأل العميل مرة واحدة، ويستجيب الخادف فقط عندما تظهر البيانات فعليًا. Long Polling يخلق طلبات فارغة أقل ويقلل حمل الشبكة.
يجب استخدام Long Polling عندما يكون WebSocket غير متاح: في الشبكات المؤسسية التي تحجب بروتوكولات غير HTTP، عند الحاجة إلى التوافق العكسي مع المتصفحات القديمة أو قيود الاستضافة. WebSocket أكثر كفاءة لتبادل البيانات عالي التردد.
وقت الانتظار الموصى به لـ Long Polling هو 30–45 ثانية. قيمة أقل (10–15 ثانية) تزيد عدد الطلبات، بينما قيمة أعلى (60+ ثانية) تخاطر بقطع الاتصال بواسطة موازنات الحمل المتوسطة. تعتمد قيمة وقت الانتظار على هندسة الشبكة ومتطلبات زمن الاستجابة.
العيوب الرئيسية لـ Long Polling هي استهلاك عالي للذاكرة على الخادم عند احتفاظ آلاف الاتصالات، صعوبة التوسع الأفقي (يتطلب قائمة أحداث مركزية) وعدم وجود اتصال ثنائي حقيقي — تلزم طلبات POST منفصلة لإرسال البيانات إلى الخادم.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.