أحداث مرسلة من الخادم في PHP: وقت فعلي لا يعض
\n\nهل تساءلت يومًا لماذا يتم تحديث تطبيق المراسلة المفضل لديك أو بورصة العملات الرقمية بشكل فوري، بينما موقعك على PHP لا يزال يجبر المستخدم على الضغط على F5؟ يبدو أن الوقت الفعلي هو حكر على المختارين، المسلحين بـ Node.js أو خوادم WebSocket باهظة الثمن. ولكن ماذا لو أخبرتك أن الأحداث المرسلة من الخادم (SSE) في PHP هي طريقة بسيطة وأنيقة وفعالة بشكل لا يصدق لإضافة تحديثات حية إلى مشروعك؟
\n\nمرحبًا بك في PythonLib، حيث نحطم الصور النمطية. اليوم سنشرح الأحداث المرسلة من الخادم PHP - تقنية تسمح للخادم بـ "دفع" البيانات إلى العميل عبر HTTP عادي، دون سطر واحد من سحر JavaScript (حسنًا، تقريبًا بدونه). لا بروتوكولات معقدة، لا مشاكل مع NAT والبروكسي - فقط PHP نقي ومفهوم وتدفق بيانات يجري مثل نهر جبلي.
\n\nما هي الأحداث المرسلة من الخادم ولماذا هي "الرصاصة الفضية" لـ PHP؟
\n\nSSE هي مواصفات HTML5 تسمح للخادم بإرسال عدد غير محدود من الأحداث إلى العميل عبر اتصال HTTP واحد طويل العمر. على عكس WebSocket، وهو ثنائي الاتجاه، يعمل SSE فقط "من الخادم إلى العميل". وهذا رائع! بالنسبة لـ 90% من المهام (الإشعارات، خلاصات الأخبار، المراقبة، مؤشرات البورصة)، ليست هناك حاجة للتغذية الراجعة. لماذا تسحب مدفعية ثقيلة بينما يمكنك استخدام سلاح مشاة خفيف؟
\n\nالمزايا الرئيسية لـ إشعارات الوقت الفعلي PHP عبر SSE:
\n- \n
- سهولة التنفيذ - على جانب الخادم، هو مجرد سكريبت PHP عادي لا يغلق الاتصال. \n
- إعادة الاتصال التلقائي - المتصفح يعيد الاتصال بنفسه إذا انقطع الاتصال. \n
- يعمل عبر أي بروكسي - HTTP/1.1، HTTP/2، Nginx، Apache - كل شيء جاهز فورًا. \n
- استهلاك منخفض للموارد - على عكس polling، لا تتكرر الطلبات كل ثانيتين. \n
بالطبع، لدى SSE قيود: الحد الأقصى لعدد الاتصالات المتزامنة في المتصفح (6 لكل نطاق)، وهي غير مدعومة في Internet Explorer القديم. ولكن بالنسبة للتطبيقات الحديثة، هذه ليست مشكلة. وإذا كنت بحاجة إلى المزيد - استخدم HTTP/2، حيث يتم إزالة هذه القيود.
\n\nكيف تعمل الأحداث المرسلة من الخادم على PHP: من النظرية إلى التطبيق
\n\nلنتخيل أن سكريبت PHP الخاص بك هو نادل. الطلب العادي هو عندما يأتي العميل، ويطلب مشروبًا (يقوم بطلب GET)، ويصب النادل (ينفذ الكود)، ويسلم الكأس (يرسل الرد)، ويغلق البار. في SSE، يأتي العميل ويطلب "من فضلك، اسكب لي كوكتيلًا جديدًا كل 5 ثوانٍ"، ويبدأ النادل في صب تيار لا نهائي، دون إغلاق الصنبور.
\n\nمن الناحية الفنية، يبدو الأمر كما يلي:
\n- \n
- يقوم العميل (المتصفح) بإنشاء كائن
EventSourceويرسل طلب GET إلى سكريبت PHP. \n - يقوم الخادم بتعيين الرأس
Content-Type: text/event-streamويعطل التخزين المؤقت. \n - يدخل الخادم في حلقة لا نهائية، ويرسل البيانات بتنسيق
data: {"message": "hello"}\\n\\n. \n - عندما يحتاج الخادم إلى التوقف (أو أغلق العميل علامة التبويب)، يتم قطع الاتصال. \n
المثال الأول: "مرحبًا بالعالم" بسيط على SSE في PHP
\n\nلننشئ ملفًا باسم sse.php. سيكون هذا هو "محركنا الدائم":
<?php\n// sse.php - أبسط خادم أحداث مرسلة من الخادم\nheader('Content-Type: text/event-stream');\nheader('Cache-Control: no-cache');\nheader('Connection: keep-alive');\nheader('X-Accel-Buffering: no'); // لـ Nginx\n\n// تأكد من أن PHP لا يقطع التنفيذ\nset_time_limit(0);\n\n$counter = 0;\n\nwhile (true) {\n $counter++;\n $data = ['time' => date('H:i:s'), 'count' => $counter];\n \n // إرسال الحدث\n echo "id: {$counter}\\n";\n echo "event: update\\n";\n echo "data: " . json_encode($data) . "\\n\\n";\n \n //