Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get List Of Connected Users From Ratchet WebSocket #1022

Open
varun7952 opened this issue Jun 16, 2023 · 3 comments
Open

Get List Of Connected Users From Ratchet WebSocket #1022

varun7952 opened this issue Jun 16, 2023 · 3 comments

Comments

@varun7952
Copy link

varun7952 commented Jun 16, 2023

I am trying my hands on websockets and i think its working too. I created a dummy php file to start a websocket server then at onOpen i am attaching to user ID of each clients so i can access it later or can use their ID to send message to them. After starting and connecting to the websocket, i try to access list of users connected to the websocket like this

<?php 
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once('websocket.php');

// Test Connected Device/Users
$connectedClients = $webSocketServer->getClients();
foreach ($connectedClients as $userId => $client) {
    echo "User ID: $userId, Connection: $client\n";
}



?>

This file shows error that port is already in use, its right because websocket server is running on 20081 port and all users connected to websocket on this port too.

<br />
<b>Fatal error</b>:  Uncaught RuntimeException: Failed to listen on &quot;tcp: //0.0.0.0:20081&quot;: Address already in use (EADDRINUSE) in /home/bitnami/vendor/react/socket/src/TcpServer.php:184
Stack trace:
#0 /home/bitnami/vendor/react/socket/src/Server.php(77): React\Socket\TcpServer-&gt;__construct()
#1 /home/bitnami/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php(59): React\Socket\Server-&gt;__construct()
#2 /opt/bitnami/apache/htdocs/net/websocket.php(171): Ratchet\Server\IoServer: :factory()
#3 /opt/bitnami/apache/htdocs/net/test.php(6): require_once('/opt/bitnami/ap...')
#4 {main
}
  thrown in <b>/home/bitnami/vendor/react/socket/src/TcpServer.php</b> on line <b>184</b><br />

Websocket

<?php

require_once("/home/bitnami/vendor/autoload.php");
use Ratchet\MessageComponentInterface;;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

class WebSocketHandler implements MessageComponentInterface {
    private $clients;
    public function __construct() {
        $this->clients = new \SplObjectStorage();
    }
    

    public function onOpen(ConnectionInterface $conn) {
        // Handle new WebSocket connection
        
        $request = $conn->httpRequest;
        // Get the action
        $action = $request->getHeaderLine("action");
        // Check if the action is "addClient"
        if ($action === "addClient") {
            // Add the user to the list of connected users
            $userId = $request->getHeaderLine('userId');            
            // Save the user ID in the resourceId property of the connection
            $conn->resourceId = $userId;
            // Add the connection to the clients list
            $this->clients->attach($conn, $userId);
        }
        file_put_contents('zee1.log',print_r($userId.' '.$action,true));        
    }

    

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        $conn->close();
    }
    
    private function findClientConnection($userId) {
        foreach ($this->clients as $client) {
            if ($client->resourceId === $userId) {
                return $client;
            }
        }
        return null;
    }

    public function getClients(){
        $connectedClients = [];
        foreach ($this->clients as $client) {
            $connectedClients[$client->resourceId] = $client;
        }
        return $connectedClients;
    }   
    
}
    
$webSocketServer = new WebSocketHandler();

    $server = IoServer::factory(
            new HttpServer(
                new WsServer(
                    $webSocketServer
                )
            ),
            20081
        );


    $server->run();

I stuck to get connected users from websocket, but not able to find any docs or help which can help me to get active/connected users (with their IDs).

@SimonFrings
Copy link

@varun7952 Thanks for bringing this up 👍

I can see in your example above that you use SplObjectStorage in order to store your clients, attach them inside the onOpen() method and detach them in onClose(). So it seems to me that you're already keeping track of your connected clients, what exactly is the problem you're facing here (What makes you think it doesn't work)?

@varun7952
Copy link
Author

@SimonFrings Is there any method or function which i can call to get ID of users currently connected to websocket. Right now i am doing it by saving user id at onOpen in text file and delete at onClose but i guess this is the hack not a solution. Can you please look at this point ?

@programarivm
Copy link

@varun7952 you may also want to store the connected clients in a PHP array.

    // ...
    
    public function onOpen(ConnectionInterface $conn)
    {
        $this->clients[$conn->resourceId] = $conn;

        // ...
    }
    
    // ...

Then, the ids can be obtained using PHP's built-in function array_keys.

    array_keys($this->clients);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants