مقدمة: لماذا موقعك "بطيء" في الوقت الفعلي؟
\n\nتخيل أنك دخلت إلى موقع تداول، وسعر الدولار يتجدد فقط بعد إعادة تحميل الصفحة. أو أنك أرسلت رسالة في الدردشة، ورآها المحاور بعد 10 ثوانٍ. مألوف؟ هذا هو ألم أي مطور يحاول جعل التطبيق "حيًا".
\n\nفي عالم PHP، حيث يعيش كل طلب حياة قصيرة، فإن تنفيذ وظائف الوقت الفعلي مهمة غير تافهة. النهجان الرئيسيان اللذان يأتيان للإنقاذ هما Long polling و WebSocket. أيهما تختار لمشروعك في PHP؟ دعنا نفهم بدون حشو، مع أمثلة أكواد حية.
\n\nما هو Long polling في PHP؟ طلب طويل بسر
\n\nLong 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\nfunction 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
سلبيات Long polling
\n- \n
- الضغط على الخادم — كل طلب "طويل" يبقي عملية PHP-FPM مشغولة. مع 1000 مستخدم، ستحتاج إلى 1000 عملية. \n
- التأخير (زمن الوصول) — الحد الأدنى للتأخير = ثانية واحدة (بسبب sleep). إذا قللت sleep، سيبدأ المعالج في الاحتراق. \n
- صعوبة التوسع — Long polling لا يتوافق جيدًا مع موازنات التحميل (تحتاج لربط المستخدم بخادم معين). \n
WebSocket في PHP: وقت فعلي حقيقي بدون تنازلات
\n\nWebSocket هو قناة اتصال ثنائية الاتجاه كاملة عبر TCP. بعد المصافحة عبر HTTP،