مقدمة إلى WebSocket في PHP: من النظرية إلى التطبيق
تتطلب تطبيقات الويب الحديثة بشكل متزايد نقلًا فوريًا للبيانات بين العميل والخادم. دورة طلب-استجابة HTTP التقليدية، القائمة على long polling أو طلبات AJAX الدورية، لم تعد تفي بمتطلبات الوقت الفعلي. هنا يأتي دور بروتوكول WebSocket — وهي تقنية تتيح إنشاء اتصال ثنائي الاتجاه دائم بين المتصفح والخادم.
في هذه المقالة، سنشرح كيفية إنشاء تطبيقات الوقت الفعلي (real-time) باستخدام PHP مع WebSocket. ستتعلم كيفية تثبيت مكتبة الخادم Ratchet، وكتابة دردشة بسيطة ونظام إشعارات، بالإضافة إلى العقبات المحتملة التي قد تواجهك. المادة موجهة للمطورين الملمين بأساسيات PHP وJavaScript.
ما هو WebSocket ولماذا هو مهم لـ PHP؟
WebSocket هو بروتوكول يعمل فوق TCP. يبدأ كطلب HTTP (مصافحة)، ثم يتم "ترقية" الاتصال إلى قناة ثنائية الاتجاه كاملة. على عكس HTTP:
- يمكن للخادم إرسال البيانات إلى العميل دون طلب مسبق.
- يظل الاتصال مفتوحًا، مما يوفر الموارد من عمليات المصافحة المتكررة.
- زمن انتقال نقل البيانات ضئيل — ميلي ثوانٍ مقابل ثوانٍ في long polling.
كانت PHP تُعتبر تقليديًا لغة غير مناسبة لمهام الوقت الفعلي بسبب نموذجها "طلب واحد — عملية واحدة". ومع ذلك، تتيح المكتبات الحديثة مثل Ratchet و ReactPHP تشغيل عمليات PHP طويلة الأمد تعمل كخوادم WebSocket مستقلة. هذا يفتح إمكانيات لـ:
- الدردشات والمراسلات الفورية عبر الإنترنت.
- أنظمة الإشعارات (رسائل جديدة، طلبات، تنبيهات).
- التحرير المشترك للمستندات.
- منصات الألعاب والتداول.
تثبيت وإعداد خادم WebSocket على PHP باستخدام Ratchet
للعمل مع WebSocket في PHP، سنستخدم مكتبة Ratchet (المبنية على ReactPHP). يتم التثبيت عبر Composer.
الخطوة 1. إنشاء المشروع وتثبيت التبعيات
mkdir websocket-phpcd websocket-phpcomposer require cboden/ratchetبعد التثبيت، ستظهر Ratchet وReactPHP في مجلد vendor.
الخطوة 2. إنشاء فئة خادم WebSocket
أنشئ ملفًا باسم server.php:
<?phpuse Ratchet\\MessageComponentInterface;use Ratchet\\ConnectionInterface;
class ChatServer implements MessageComponentInterface { protected $clients;
public function __construct() { $this->clients = new \\SplObjectStorage; }
public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo "اتصال جديد: {$conn->resourceId}"; }
public function onMessage(ConnectionInterface $from, $msg) { foreach ($this->clients as $client) { if ($from !== $client) { $client->send($msg); } } }
public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); echo "قطع الاتصال: {$conn->resourceId}"; }
public function onError(ConnectionInterface $conn, \\Exception $e) { echo "خطأ: {$e->getMessage()}"; $conn->close(); }}الخطوة 3. تشغيل الخادم
أضف كود التشغيل في server.php:
use Ratchet\\Server\\IoServer;use Ratchet\\Http\\HttpServer;use Ratchet\\WebSocket\\WsServer;
require __DIR__ . '/vendor/autoload.php';
$server = IoServer::factory( new HttpServer( new WsServer( new ChatServer() ) ), 8080);
echo "خادم WebSocket يعمل على المنفذ 8080";$se