Search code examples
phpwebsocketphpwebsocket

Show message to a group of users instead of all users using Websocket in php


I am developing a online video chat application in which a group of users can see and send message to the model room in which they are present. For this I am using websocket and php.

But when a user sending any mesages it is going to all users instead of the room in which he/she is present. Below is my sample code.

function send_message($msg) {
    global $clients;
    foreach ($clients as $changed_socket) {
        @socket_write($changed_socket, $msg, strlen($msg));
    }
    return true;
}

Please give your valuable feedback.


Solution

  • From the code provided, it appears that your $clients array holds only the socket handle for that specific connection.

    Find the line in your server that has the function socket_accept(). It will probably look like:

    $clients[] = socket_accept($socket);
    

    My personal choice for a quick and dirty fix would be to change it as follows:

    $handle = socket_accept($socket);
    $client = array('handle' => $handle,
                    'rooms' => array(),
                    // additional properties...
                   );
    $clients[] = $client;
    

    Then, when you want to send a message to a specific room:

    function send_message($message, $handle) {
        socket_write($handle, $message, strlen($message);
    }
    
    function broadcast($message, $room = null) {
        global $clients;
        foreach ($clients as $client) {
            if (is_null($room) || in_array($room, $client['rooms'])) {
                send_message($message, $client['handle']);
            }
        }
    }
    
    broadcast('This message will only go to users in the room "lobby"', 'lobby');
    broadcast('This message will go to everybody on the server.');
    

    A better, long term solution is to create a user class and keep a list of instances, but the basics are the same: assign the handle to a property rather than passing the handles around raw.