public function onData(int $clientId, Websocket\Message $msg) { // yielding $msg buffers the complete payload into a single string. For very large payloads, you may want to // stream those instead of buffering them. $body = (yield $msg); // We use the IP as name for this simple chat app. $ip = $this->connections[$clientId]; // If someone mentions an IP, we send the message only to clients with that IP and the sender itself. if (preg_match("~@(\\d+\\.\\d+\\.\\d+\\.\\d+)\\b~", $body, $match)) { list($all, $receiver) = $match; $payload = $ip . " (private): " . substr($body, strlen($all)); $clients = array_keys($this->ips[$receiver] ?? []); if (!empty($clients)) { $this->endpoint->send($clients, $payload); } $this->endpoint->send($clientId, $payload); } else { $payload = $ip . ": " . $body; $this->endpoint->send(null, $payload); } }
protected function initUserSubscription() { $subscription = $this->eventSub->subscribe("chat:user"); $subscription->watch(function ($payload) { if (empty($this->user2sessions[$payload->user_id])) { return; } $sessions = $this->user2sessions[$payload->user_id]; $clients = []; foreach (array_keys($sessions) as $sessionId) { $clients = array_merge($this->session2clients[$sessionId]); } $this->endpoint->broadcast(json_encode(["status" => "event", "type" => $payload->type, "data" => $payload->payload]), $clients); }); $subscription->when(function ($error) { if ($error) { (new Pause(1000))->when(function () { $this->initUserSubscription(); }); } }); }