WebSocket على PHP: إنشاء تطبيقات الوقت الفعلي المتقدمة

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

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

ابدأ الدورة

WebSocket على PHP: من النظرية إلى تطبيق الوقت الفعلي الصناعي



أحدث بروتوكول WebSocket ثورة في تطوير الويب، مما سمح بإنشاء قنوات اتصال ثنائية الاتجاه كاملة بين العميل والخادم. على عكس AJAX التقليدي (الاستقصاء الطويل، أحداث مرسلة من الخادم)، يوفر WebSocket اتصالاً مستمراً بأقل تكاليف إضافية. لمطور PHP، الانتقال من الأمثلة الأساسية لـ"خادم الصدى" إلى تطبيق الوقت الفعلي الصناعي هو تحدٍ كبير، يتعلق بإدارة الحالة، التوسع، والمعالجة غير المتزامنة.



في هذه المقالة، سنستعرض التقنيات المتقدمة للعمل مع WebSocket على PHP: بنية دردشة متعددة المستخدمين، التكامل مع Redis للتوسع الأفقي، معالجة المهام الخلفية، وتحسين الأداء.



1. بنية خادم WebSocket المتقدم على Ratchet



مكتبة Ratchet (المبنية على ReactPHP) تظل المعيار الذهبي لـ WebSocket على PHP. ومع ذلك، للحلول الإنتاجية، لا يكفي onMessage البسيط. دعنا نستعرض بنية مكوناتية مع فصل المسؤوليات:



<?phpuse Ratchet\\MessageComponentInterface;use Ratchet\\ConnectionInterface;use React\\EventLoop\\LoopInterface;

class RealTimeHub implements MessageComponentInterface { private $clients; private $loop; private $redis; private $userRegistry;

public function __construct(LoopInterface $loop, \\Redis $redis) { $this->clients = new \\SplObjectStorage; $this->loop = $loop; $this->redis = $redis; $this->userRegistry = []; }

public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo "اتصال جديد: {$conn->resourceId}"; }

public function onMessage(ConnectionInterface $from, $msg) { $data = json_decode($msg, true);

switch ($data['type'] ?? '') { case 'auth': $this->handleAuth($from, $data); break; case 'message': $this->handleMessage($from, $data); break; case 'subscribe': $this->handleSubscribe($from, $data); break; default: $from->send(json_encode(['error' => 'أمر غير معروف'])); } }

public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); // تنظيف تسجيل المستخدم if (isset($conn->userId)) { unset($this->userRegistry[$conn->userId]); } }

public function onError(ConnectionInterface $conn, \\Exception $e) { $conn->close(); }

private function handleAuth(ConnectionInterface $conn, array $data) { $token = $data['token'] ?? ''; // التحقق من JWT $userId = $this->validateToken($token); if ($userId) { $conn->userId = $userId; $this->userRegistry[$userId] = $conn; $conn->send(json_encode(['type' => 'auth_ok'])); } else { $conn->send(json_encode(['type' => 'auth_fail'])); } }

private function handleMessage(ConnectionInterface $from, array $data) { $targetUserId = $data['to'] ?? null; if ($targetUserId && isset($this->userRegistry[$targetUserId])) { $this->userRegistry[$targetUserId]->send(json_encode([ 'type' => 'message', 'from' => $from->userId ?? 'مجهول', 'text' => $data['text'] ])); } }

private function validateToken(string $token): ?int { // محاكاة التحقق من JWT $payload = json_decode(base64_decode(explode('.', $token)[1] ?? ''), true); return $payl

المدونات

توصيات الكتب