Long polling مقابل WebSocket في PHP: أيهما تختار لمشروع الوقت الفعلي

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا موقعك "بطيء" في الوقت الفعلي؟

\n\n

تخيل أنك دخلت إلى موقع تداول، وسعر الدولار يتجدد فقط بعد إعادة تحميل الصفحة. أو أنك أرسلت رسالة في الدردشة، ورآها المحاور بعد 10 ثوانٍ. مألوف؟ هذا هو ألم أي مطور يحاول جعل التطبيق "حيًا".

\n\n

في عالم PHP، حيث يعيش كل طلب حياة قصيرة، فإن تنفيذ وظائف الوقت الفعلي مهمة غير تافهة. النهجان الرئيسيان اللذان يأتيان للإنقاذ هما Long polling و WebSocket. أيهما تختار لمشروعك في PHP؟ دعنا نفهم بدون حشو، مع أمثلة أكواد حية.

\n\n

ما هو Long polling في PHP؟ طلب طويل بسر

\n\n

Long polling هو خدعة أنيقة تسمح بمحاكاة اتصال الوقت الفعلي باستخدام طلبات HTTP العادية. يرسل العميل طلبًا إلى الخادم، لكن الخادم لا يرد فورًا. يبقي الاتصال مفتوحًا حتى يظهر حدث جديد (مثل رسالة جديدة في الدردشة). بمجرد حدوث الحدث، يرسل الخادم الرد، ويعالجه العميل وينشئ فورًا طلبًا "طويلاً" جديدًا.

\n\n

كيف يعمل في PHP: مثال بسيط

\n\n

لنفترض أن لدينا دردشة بسيطة. يرسل العميل طلب AJAX إلى سكريبت PHP الذي "يعلق" في حلقة حتى تظهر رسالة جديدة في قاعدة البيانات.

\n\n
<?php\n// long_polling.php\nheader('Content-Type: application/json');\nheader('Cache-Control: no-cache');\n\n$lastMessageId = $_GET['last_id'] ?? 0;\n$timeout = 30; // ننتظر حتى 30 ثانية\n$startTime = time();\n\nwhile (time() - $startTime < $timeout) {\n    // محاكاة فحص قاعدة البيانات (في الواقع - استعلام MySQL/PostgreSQL)\n    $newMessages = getNewMessagesFromDB($lastMessageId);\n    \n    if (!empty($newMessages)) {\n        echo json_encode([\n            'status' => 'success',\n            'messages' => $newMessages\n        ]);\n        exit;\n    }\n    \n    // ننام لمدة ثانية واحدة لعدم إرهاق المعالج\n    sleep(1);\n}\n\n// إذا لم يصل شيء خلال 30 ثانية\necho json_encode(['status' => 'timeout', 'messages' => []]);\nexit;\n?>
\n\n

على جانب العميل (JavaScript) يبدو الأمر هكذا:

\n\n
function startLongPolling(lastId) {\n    fetch('/long_polling.php?last_id=' + lastId)\n        .then(response => response.json())\n        .then(data => {\n            if (data.status === 'success') {\n                data.messages.forEach(msg => addMessageToChat(msg));\n                startLongPolling(data.messages[data.messages.length - 1].id);\n            } else {\n                startLongPolling(lastId); // مهلة — فقط نعيد التشغيل\n            }\n        })\n        .catch(() => setTimeout(() => startLongPolling(lastId), 1000));\n}\n
\n\n

إيجابيات Long polling في PHP

\n
    \n
  • سهولة التنفيذ — لا حاجة لخوادم إضافية أو مكتبات. كل شيء يعمل على Apache/Nginx + PHP-FPM العادي.
  • \n
  • التوافق — يعمل في كل مكان يوجد فيه HTTP. لا مشاكل مع البروكسي أو جدران الحماية المؤسسية.
  • \n
  • عتبة دخول منخفضة — إذا كنت تعرف PHP و AJAX، يمكنك بالفعل عمل Long polling.
  • \n
\n\n

سلبيات Long polling

\n
    \n
  • الضغط على الخادم — كل طلب "طويل" يبقي عملية PHP-FPM مشغولة. مع 1000 مستخدم، ستحتاج إلى 1000 عملية.
  • \n
  • التأخير (زمن الوصول) — الحد الأدنى للتأخير = ثانية واحدة (بسبب sleep). إذا قللت sleep، سيبدأ المعالج في الاحتراق.
  • \n
  • صعوبة التوسع — Long polling لا يتوافق جيدًا مع موازنات التحميل (تحتاج لربط المستخدم بخادم معين).
  • \n
\n\n

WebSocket في PHP: وقت فعلي حقيقي بدون تنازلات

\n\n

WebSocket هو قناة اتصال ثنائية الاتجاه كاملة عبر TCP. بعد المصافحة عبر HTTP،

المدونات

توصيات الكتب