resourceId === $connection2->resourceId; } private function getConnectionIndex(ConnectionInterface $connection): int | null { foreach ($this->connectionsData as $i => $connectionData) { if ($this->isSameConnection($connection, $connectionData["connection"])) { return $i; } } return null; } private function sendToAllAuthenticated(string $username, string $msg): void { foreach ($this->connectionsData as $connectionData) { if ($connectionData["username"] !== $username) { $connectionData["connection"]->send("{\"sender\": \"{$username}\",\"msg\": \"{$msg}\"}"); } } } private function deleteGivenId(int $id): void { foreach ($this->connectionsData as $i => $connectionData) { if ($connectionData["connection"]->resourceId === $id) { array_splice($this->connectionsData, $i, 1); return; } } } public function onOpen(ConnectionInterface $conn): void { $this->connectionsData[] = [ "connection" => $conn, "username" => null ]; echo "New connection: {$conn->resourceId}\n"; } public function onMessage(ConnectionInterface $from, $msg): void { $decodedMsg = json_decode($msg, true); if (!$decodedMsg) { $from->send("{\"error\": \"not or empty json\"}"); return; } $index = $this->getConnectionIndex($from); if ($index === null) return; if ($this->connectionsData[$index]["username"]) { $msgContent = $decodedMsg["message"] ?? null; if ($msgContent) { $this->sendToAllAuthenticated($this->connectionsData[$index]["username"], $msgContent); $from->send("{\"success\": \"message send\"}"); return; } $from->send("{\"error\": \"no message\"}"); return; } $token = $decodedMsg["token"] ?? null; if ($token) { $tokenUser = TokenHandler::getTokenOwnership($token); if ($tokenUser) { $this->connectionsData[$index]["username"] = $tokenUser; $from->send("{\"success\": \"authenticated\"}"); return; } $from->send("{\"error\": \"invalid token\"}"); return; } $from->send("{\"error\": \"you are not authenticated\"}"); } public function onClose(ConnectionInterface $conn): void { $this->deleteGivenId($conn->resourceId); echo "Connection {$conn->resourceId} closed\n"; } public function onError(ConnectionInterface $conn, \Exception $e): void { echo "Error: {$e->getMessage()}\n"; $this->deleteGivenId($conn->resourceId); $this->onClose($conn); } } $routes = new RouteCollection(); $routes->add("login", new Route("/login", ["_controller" => new LoginController()])); $routes->add("register", new Route("/register", ["_controller" => new RegisterController()])); $routes->add("ws", new Route("/ws", ["_controller" => new WsServer(new WebSocketServer())])); $server = IoServer::factory( new HttpServer(new Router(new UrlMatcher($routes, new RequestContext()))), 8080 ); echo "Server running on http://localhost:8080\n"; $server->run();