9

I have process on server which acts as WebSocket server (not written in Ratchet). I want to be able to send data to this process using PHP (as client).

I found a lot of examples to send as TCP like this:

<?php
  $addr = gethostbyname("localhost");

  $client = stream_socket_client("tcp://$addr:8887", $errno, $errorMessage);

  if ($client === false) {
      throw new UnexpectedValueException("Failed to connect: $errorMessage");
  }

  fwrite($client, "GET / HTTP/1.0\r\nHost: localhost\r\nAccept: */*\r\n\r\n");
  echo stream_get_contents($client);
?>

All I need I to send message to the process and close the connection. The result that I expect is the result from the webSocket will be later printed or "echo" to the PHP page.

Is there a way to make it work with curl in php?

Michael Gaskill
  • 7,913
  • 10
  • 38
  • 43
Pini Cheyni
  • 5,073
  • 2
  • 40
  • 58
  • What is the result of your code ? – JesusTheHun Jun 02 '16 at 15:27
  • can you download php libraries to use? if yes you cna use one of those to make a websocket client. If not, you will most likely need to write some javascript code for a client. – jgr208 Jun 02 '16 at 16:03
  • The result that I expect is the result from the webSocket will be later printed or "echo" to the php page. – Pini Cheyni Jun 03 '16 at 04:49
  • @jgr208 - I can download php libraries but in this specific case the php page is the client so why should I need to add JS ? – Pini Cheyni Jun 03 '16 at 04:51
  • @PiniCheyni i meant if you can't download them then you would have to use pure js since you can you don't need to use pure js and can use php. – jgr208 Jun 06 '16 at 13:46
  • I want to clarify it: I'm running on my local windows machine process which implements websocket and I'm able to communicate from my web Browser, Now there are request coming from users which **PHP** updates data to DB and I need it to send data to this process which runs on the same machine where the APACHE server runs. This has nothing to do with JS. – Pini Cheyni Jun 07 '16 at 10:43

1 Answers1

16

I have found this code on github, (I can't find the exact repo where I got it from because I have looked and tried a lot of them)

<?php
class WebsocketClient {

    private $_Socket = null;

    public function __construct($host, $port) {
        $this->_connect($host, $port);
    }

    public function __destruct() {
        $this->_disconnect();
    }

    public function sendData($data) {
        // send actual data:
        fwrite($this->_Socket, "\x00" . $data . "\xff") or die('Error:' . $errno . ':' . $errstr);
        $wsData = fread($this->_Socket, 2000);
        $retData = trim($wsData, "\x00\xff");
        return $retData;
    }

    private function _connect($host, $port) {
        $key1 = $this->_generateRandomString(32);
        $key2 = $this->_generateRandomString(32);
        $key3 = $this->_generateRandomString(8, false, true);

        $header = "GET /echo HTTP/1.1\r\n";
        $header.= "Upgrade: WebSocket\r\n";
        $header.= "Connection: Upgrade\r\n";
        $header.= "Host: " . $host . ":" . $port . "\r\n";
        $header.= "Origin: http://localhost\r\n";
        $header.= "Sec-WebSocket-Key1: " . $key1 . "\r\n";
        $header.= "Sec-WebSocket-Key2: " . $key2 . "\r\n";
        $header.= "\r\n";
        $header.= $key3;


        $this->_Socket = fsockopen($host, $port, $errno, $errstr, 2);
        fwrite($this->_Socket, $header) or die('Error: ' . $errno . ':' . $errstr);
        $response = fread($this->_Socket, 2000);

        /**
         * @todo: check response here. Currently not implemented cause "2 key handshake" is already deprecated.
         * See: http://en.wikipedia.org/wiki/WebSocket#WebSocket_Protocol_Handshake
         */
        return true;
    }

    private function _disconnect() {
        fclose($this->_Socket);
    }

    private function _generateRandomString($length = 10, $addSpaces = true, $addNumbers = true) {
        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"§$%&/()=[]{}';
        $useChars = array();
        // select some random chars:    
        for ($i = 0; $i < $length; $i++) {
            $useChars[] = $characters[mt_rand(0, strlen($characters) - 1)];
        }
        // add spaces and numbers:
        if ($addSpaces === true) {
            array_push($useChars, ' ', ' ', ' ', ' ', ' ', ' ');
        }
        if ($addNumbers === true) {
            array_push($useChars, rand(0, 9), rand(0, 9), rand(0, 9));
        }
        shuffle($useChars);
        $randomString = trim(implode('', $useChars));
        $randomString = substr($randomString, 0, $length);
        return $randomString;
    }

}

$WebSocketClient = new WebsocketClient('localhost', 8887);
echo $WebSocketClient->sendData("MyUserNameFromPHP");
unset($WebSocketClient);
?>

Out of 7 php websocket clients that I tried, this is the only one that I was able to work with. It doesn't requires any external files or frameworks. This is simple implementation for executing short command that doesn't require persistent connection to webSocket server.

I hope it helps you guys , and you will save some time !!!

Pini Cheyni
  • 5,073
  • 2
  • 40
  • 58
  • 1
    This solution seems working. Could you mark your question as solved? – Maki Vlach Sep 11 '18 at 23:05
  • 3
    code provided above is located at https://github.com/edtsz/PHP-WebSocket/blob/master/client.php – Velaro Jan 15 '19 at 11:54
  • It works perfectly with a C# application so i can make a web client for it – edisonmecaj Jul 16 '19 at 10:43
  • 2
    @pini-cheyni I am not able to send data using `sendData` function. No response is shown on my socket server on Django. Can anyone help me out? – AMAN SHARMA Dec 30 '19 at 13:14
  • @AMANSHARMA any luck I am also in similar situation, I have tried a lot but nothing seems to go through. I am using ratchet as socket server with react js as client which works fine, but when I try to use php as cient it just doesn't work. my purpose is to update react-webpage when new webhook is received. – Mayank Tiwari May 14 '20 at 21:40
  • @MayankTiwari Yeah I was able to create one WebSocket Client on PHP. I have created a GitHub Gist for it. Here is the link - https://gist.github.com/algomaster99/b02a8723dc265f8e36c6830e378ade12. – AMAN SHARMA May 16 '20 at 15:52
  • Thanks for sharing @AMANSHARMA But multiple things i tried didn't work finally I found https://github.com/ratchetphp/Pawl and it worked.I guess it has better compatibility with ratchet socket server. – Mayank Tiwari May 16 '20 at 22:16
  • sendData is not working that way, because you need hybi10 frame encoding. See https://stackoverflow.com/questions/42955033/php-client-web-socket-to-send-messages – Cody Tookode Jun 10 '23 at 15:15