Skip to content
Advertisement

PHP Websocket Client – Keep connection open

I am using PHP-WSS in a laravel application and need to keep a websocket client open to receive various messages from the websocket server.

So far I built a CLI php script that I can execute and wait for messages to arrive.

I built the following function to test…

The question is, to keep the connection open for any messages that might be sent from the server, is it a good approach to do it as below using a while(true) loop? Is there anyway I can do this better? (To me it looks dirty and wish to improve it and do it properly)

function testWebsocketClient() {
    $url = 'wss://example.com/?token=xyz123456';
    $client = new WebSocketClient($url, new ClientConfig());
    while(true){
        sleep(5);
        $client->send('test');
        $return = $client->receive(); // test received OK
    }
    return $return;
}

UPDATE: Anyone using PHP-WSS I found a bug in Connection.php in broadCast method.

Original function tries to send on a dead connection, which shows the following error Empty read; connection dead? (Note the EOF = true)

public function broadCast(string $data): void
{
    foreach ($this->clients as $client) {
        if (is_resource($client) ) { // check if not yet closed/broken etc
            fwrite($client, $this->encode($data));
        } else {
            echo 'Skipping a closed connection';
        }
    }
}

I changed it to

public function broadCast(string $data): void
{
    foreach ($this->clients as $client) {
        //echo PHP_EOL. stream_get_status($client) .PHP_EOL;
        $clientMeta = ( stream_get_meta_data($client) );
        $clientEof = $clientMeta['eof'];
        if (is_resource($client) && $clientEof == false ) { // check if not yet closed/broken etc
            fwrite($client, $this->encode($data));
        } else {
            echo 'Skipping a closed connection';
        }
    }
}

Advertisement

Answer

Since the php script that renders the page finishes execution, you need to implement websockets on the client itself using a js script

<?php 
   // here output your page
   wss_path = 'wss://example.com/?token=xyz123456';
?>

// JS script (see its working results in console by pressing `F12`)
<script>
  let socket = new WebSocket(<?= wss_path ?>);

  socket.onopen = function(e) {
    console.log('[open] Connection opened');
    socket.send("Hi! I am a new web-socket client.");
  };

  socket.onmessage = function(event) {
    const message = JSON.parse(event.data);
    console.log('From the server:', message);
  };

  socket.onclose = function(event) {
    if (event.wasClean) {
      console.log(`[close] Connetion closed clearly, code=${event.code} reason=${event.reason}`);
    } else {
      console.log('[close] Сonnection closed unexpectedly');
    }
  };

  socket.onerror = function(error) {
    console.log(`[error] ${error}`);
  };
</script>
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement