WebSockets في PHP: إنشاء تطبيقات الوقت الفعلي بدون سحر
\n\nهل تساءلت يومًا لماذا تصل الإشعارات في تطبيقات الويب الحديثة فورًا، وتعمل الدردشات دون الحاجة المستمرة للضغط على F5؟ السر يكمن في WebSockets. ونعم، PHP أيضًا قادرة على العمل في الوقت الفعلي. في هذه المقالة، سنفهم كيفية جعل PHP يتعامل مع WebSockets، وسنكتب دردشة حية وإشعارات، والأهم من ذلك، سنفعل ذلك بدون ألم ومكتبات إضافية.
\n\nإذا كنت معتادًا على أن PHP هي "طلب-استجابة"، فاستعد للدهشة. باستخدام WebSockets في PHP، يمكنك إنشاء تطبيقات كاملة في الوقت الفعلي: من دردشة بسيطة إلى لعبة متعددة اللاعبين. وكل هذا بلغتك المفضلة.
\n\nما هي WebSockets ولماذا هي مهمة لـ PHP؟
\n\nWebSocket هو بروتوكول اتصال ثنائي الاتجاه بين العميل والخادم. على عكس HTTP العادي، حيث يقوم العميل باستمرار باستفسار الخادم "هل هناك أخبار؟"، يحافظ WebSocket على الاتصال مفتوحًا. يرسل الخادم البيانات إلى العميل بنفسه عند ظهورها.
\n\nبالنسبة لـ PHP، هذا اختراق حقيقي. في السابق، كان الوقت الفعلي حكرًا على Node.js أو Python مع asyncio. لكن الآن، تطبيقات الوقت الفعلي على PHP أصبحت حقيقة واقعة. بفضل مكتبات مثل Ratchet وSwoole، يمكن لـ PHP العمل كعملية طويلة العمر، ومعالجة آلاف الاتصالات المتزامنة.
\n\nأين يمكن استخدام هذا؟
\n- \n
- الدردشات وتطبيقات المراسلة؛ \n
- أنظمة الإشعارات (طلبات جديدة، رسائل)؛ \n
- التحرير المشترك للمستندات؛ \n
- الألعاب والمسابقات عبر الإنترنت؛ \n
- المراقبة ولوحات المعلومات في الوقت الفعلي. \n
التحضير: ما تحتاجه للبدء
\n\nللعمل مع خادم WebSocket على PHP، سنحتاج إلى:
\n- \n
- PHP 7.4 أو أعلى (يفضل 8.x)؛ \n
- Composer - مدير الحزم؛ \n
- مكتبة Ratchet (أو Swoole للإنتاج)؛ \n
- فهم أساسي للبرمجة كائنية التوجه (OOP) والعمل مع سطر الأوامر. \n
سنقوم بتثبيت Ratchet عبر Composer:
\ncomposer require cboden/ratchet\n\nبعد التثبيت، سيظهر لديك مجلد vendor وملف composer.json. كل شيء جاهز لكتابة أول تطبيق وقت فعلي على PHP.
\n\nكتابة خادم WebSocket بسيط على PHP
\n\nلننشئ ملفًا باسم server.php. سيكون هذا هو خادم WebSocket PHP الخاص بنا، والذي يستقبل الاتصالات ويرسل الرسائل إلى جميع العملاء المتصلين.
<?php\nuse Ratchet\\Server\\IoServer;\nuse Ratchet\\Http\\HttpServer;\nuse Ratchet\\WebSocket\\WsServer;\nuse Ratchet\\MessageComponentInterface;\nuse Ratchet\\ConnectionInterface;\n\nrequire __DIR__ . '/vendor/autoload.php';\n\nclass Chat implements MessageComponentInterface {\n protected $clients;\n\n public function __construct() {\n $this->clients = new \\SplObjectStorage;\n echo "تم تشغيل الخادم!\\n";\n }\n\n public function onOpen(ConnectionInterface $conn) {\n $this->clients->attach($conn);\n echo "اتصال جديد: {$conn->resourceId}\\n";\n }\n\n public function onMessage(ConnectionInterface $from, $msg) {\n foreach ($this->clients as $client) {\n if ($from !== $client) {\n $client->send($msg);\n }\n }\n echo "رسالة من {$from->resourceId}: $msg\\n";\n }\n\n public function onClose(ConnectionInterface $conn) {\n $this->clients->detach($conn);\n echo "تم إغلاق الاتصال: {$conn->resourceId}\\n";\n }\n\n public function onError(ConnectionInterface $conn, \\Exception $e) {\n echo "خطأ: {$e->getMessage()}\\n";\n $conn->close();\n }\n}\n\n$server = IoServer::factory(\n new HttpServer(\n new WsServer(\n new Chat()\n )\n ),\n 8080\n);\n\n$server->run();\n\nلنشغل الخادم من سطر الأوامر:
\nphp server.php\n\nهذا كل شيء! الخادم يستمع على المنفذ 8080 ومستعد لاستقبال اتصالات WebSocket. الآن