أحداث الخادم المُرسلة (SSE) في PHP: إرسال البيانات في الوقت الفعلي

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

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

ابدأ الدورة

أحداث الخادم المُرسلة (SSE) في PHP: عندما يتصل الخادم بالمتصفح من تلقاء نفسه

\n\n

هل تساءلت يومًا عن كيفية عمل خلاصات الأخبار في تويتر، أو أسعار العملات في البورصة، أو الإشعارات في تطبيقات المراسلة؟ الإجابة الصحيحة هي أن البيانات تأتي تلقائيًا دون الحاجة لتحديث الصفحة أو إرسال طلبات Ajax لا نهائية. معظم المطورين يتذكرون فورًا WebSockets، لكن هناك طريقة أخرى أبسط وأكثر أناقة وهي أحداث الخادم المُرسلة (SSE).

\n\n

في هذه المقالة، سنشرح كيفية تنفيذ أحداث الخادم المُرسلة (SSE) في PHP من الصفر. ستتعلم كيفية إرسال البيانات من الخادم في الوقت الفعلي دون إثقال البنية التحتية بمكتبات معقدة. لا حاجة لـ Node.js، ولا حاجة لقوائم انتظار — فقط PHP خالص و HTML5.

\n\n

ما هي أحداث الخادم المُرسلة (SSE) ولماذا نحتاجها؟

\n\n

SSE (أحداث الخادم المُرسلة) هي معيار HTML5 يسمح للخادم بإرسال البيانات إلى العميل عبر اتصال HTTP واحد. على عكس WebSockets التي تعمل في كلا الاتجاهين، فإن SSE هي قناة أحادية الاتجاه: البيانات تنتقل فقط من الخادم إلى العميل. ولكن في هذا تكمن ميزتها الرئيسية: التنفيذ بسيط للغاية لدرجة أنه لا يتطلب أي مكتبات إضافية أو خوادم خاصة.

\n\n

أين تُستخدم أحداث الخادم المُرسلة في PHP؟

\n
    \n
  • خلاصات الأخبار والإشعارات في الوقت الفعلي
  • \n
  • مراقبة الخوادم وسجلات النظام
  • \n
  • أسعار العملات وأسعار الأسهم
  • \n
  • مؤشرات تقدم العمليات الطويلة (رفع الملفات، معالجة الفيديو)
  • \n
  • روبوتات الدردشة وأنظمة التنبيهات
  • \n
\n\n

على عكس الاستقصاء التقليدي (Polling) حيث يطلب العميل البيانات كل بضع ثوانٍ، فإن SSE في PHP ينشئ اتصالاً دائمًا لا يتطلب مصافحة متكررة أو رؤوس إضافية. هذا يوفر النطاق الترددي وموارد المعالج.

\n\n

كيف تعمل SSE: البروتوكول والرؤوس

\n\n

يعتمد SSE على استجابة HTTP عادية مع نوع محتوى خاص. يرسل الخادم البيانات بتنسيق نصي باستخدام الكلمات المفتاحية event و data و id و retry. يستقبل العميل التدفق ويعالج الأحداث فور وصولها.

\n\n

البروتوكول الأساسي يبدو كالتالي:

\n
Content-Type: text/event-stream\nCache-Control: no-cache\nConnection: keep-alive\n\ndata: مرحباً بالعالم\n\ndata: {"message": "هذا JSON"}
\n\n

كل رسالة تبدأ بـ data: يليها النص. إذا كنت بحاجة لإرسال عدة أسطر، اكتب عدة data: متتالية. السطر الفارغ \\n\\n يشير إلى نهاية الرسالة.

\n\n

كتابة أول سكريبت SSE في PHP

\n\n

لنقم بإنشاء سكريبت بسيط يرسل الوقت الحالي كل ثانيتين. هذا مثال تقليدي يظهر فورًا سحر الوقت الفعلي في PHP.

\n\n

الملف sse.php:

\n
<?php\n// تعطيل التخزين المؤقت للمخرجات\nob_implicit_flush(true);\nob_end_flush();\n\n// تعيين رؤوس SSE\nheader('Content-Type: text/event-stream');\nheader('Cache-Control: no-cache');\nheader('Connection: keep-alive');\nheader('X-Accel-Buffering: no'); // لخادم Nginx\n\nwhile (true) {\n    // تكوين البيانات\n    $data = [\n        'time' => date('H:i:s'),\n        'timestamp' => time()\n    ];\n    \n    // إرسال الحدث\n    echo "data: " . json_encode($data) . "\\n\\n";\n    \n    // التحقق مما إذا كان العميل قد أغلق الاتصال\n    if (connection_aborted()) {\n        break;\n    }\n    \n    // توقف لمدة ثانيتين\n    sleep(2);\n}\n?>
\n\n

لاحظ أننا نستخدم حلقة لا نهائية while(true)، ولكننا نتحقق دائمًا من connection_aborted(). إذا أغلق العميل علامة التبويب، سينتهي السكريبت دون إثقال الخادم.

\n\n

الآن لنكتب الجزء الخاص بالعميل باستخدام JavaScript:

\n
<!DOCTYPE html>\n<html>\n<head>\n    <title>عرض SSE في PHP</title>\n</head>\n<body>\n    <h2>الوقت الحالي من الخادم:</h2                

المدونات

توصيات الكتب