Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebSocket client in PHP? [closed]

Tags:

php

websocket

Is there a library or client for connecting to a WebSocket server from PHP? If not, is there a reason why?

(phpwebsocket only seem to have Javascript client code.)

like image 328
Christian Davén Avatar asked Aug 23 '11 12:08

Christian Davén


People also ask

Why is WebSocket connection closed?

The WebSocket is closed before the connection is established error message indicates that some client code, or other mechanism, has closed the websocket connection before the connection was fully established.

Can I reopen a closed WebSocket?

Just make a new WebSocket again. The reason a reconnect doesn't exist is because it would probably be just like creating a new one. Possible duplicate of Reconnection of client when the server reboots in WebSocket.

Does PHP support WebSocket?

Yes, it's possible to do PHP + Websocket very simply, without any third party library (like Ratchet, often mentioned). You can find more detailed instructions about this here: How to create websockets server in PHP. It uses a constantly-running PHP server, that you start from command-line with php websockets.

How long does WebSocket stay open?

A WebSocket connection can in theory last forever. Assuming the endpoints remain up, one common reason why long-lived TCP connections eventually terminate is inactivity.


2 Answers

None of the above is a good answer. Several of them are about a server, whereas the question is about a client. The code from Rodislav didn't work for me, as it didn't talk to my WebSockets server on Heroku. However, this library worked very well:

https://github.com/Devristo/phpws

UPDATE: While this code worked when all was well, there seems to be no error returns or exceptions at all, and as a result it's unusable when there's an error (e.g., the server isn't running, the address is wrong, the port is blocked, etc.). So, while it was fun to experiment with, it's not usable in production code.

like image 53
Marc Rochkind Avatar answered Sep 18 '22 13:09

Marc Rochkind


well, it's easy and you can do in this Thanks to all sources where we found answers (sorry, I can't remember all)

<?php $host = '10.9.8.173';  //where is the websocket server $port = 8575; $local = "http://mypc";  //url where this script run $data = "first message";  //data to be send  $head = "GET / HTTP/1.1"."\r\n".         "Upgrade: WebSocket"."\r\n".         "Connection: Upgrade"."\r\n".         "Origin: $local"."\r\n".         "Host: $host"."\r\n".         "Sec-WebSocket-Key: asdasdaas76da7sd6asd6as7d"."\r\n".         "Content-Length: ".strlen($data)."\r\n"."\r\n"; //WebSocket handshake $sock = fsockopen($host, $port, $errno, $errstr, 2); fwrite($sock, $head ) or die('error:'.$errno.':'.$errstr); $headers = fread($sock, 2000); echo $headers; fwrite($sock, hybi10Encode($data)) or die('error:'.$errno.':'.$errstr); $wsdata = fread($sock, 2000); var_dump(hybi10Decode($wsdata)); fclose($sock);   function hybi10Decode($data) {     $bytes = $data;     $dataLength = '';     $mask = '';     $coded_data = '';     $decodedData = '';     $secondByte = sprintf('%08b', ord($bytes[1]));     $masked = ($secondByte[0] == '1') ? true : false;     $dataLength = ($masked === true) ? ord($bytes[1]) & 127 : ord($bytes[1]);      if($masked === true)     {         if($dataLength === 126)         {            $mask = substr($bytes, 4, 4);            $coded_data = substr($bytes, 8);         }         elseif($dataLength === 127)         {             $mask = substr($bytes, 10, 4);             $coded_data = substr($bytes, 14);         }         else         {             $mask = substr($bytes, 2, 4);                    $coded_data = substr($bytes, 6);                 }            for($i = 0; $i < strlen($coded_data); $i++)         {                    $decodedData .= $coded_data[$i] ^ $mask[$i % 4];         }     }     else     {         if($dataLength === 126)         {                      $decodedData = substr($bytes, 4);         }         elseif($dataLength === 127)         {                        $decodedData = substr($bytes, 10);         }         else         {                            $decodedData = substr($bytes, 2);                }            }         return $decodedData; }   function hybi10Encode($payload, $type = 'text', $masked = true) {     $frameHead = array();     $frame = '';     $payloadLength = strlen($payload);      switch ($type) {         case 'text':             // first byte indicates FIN, Text-Frame (10000001):             $frameHead[0] = 129;             break;          case 'close':             // first byte indicates FIN, Close Frame(10001000):             $frameHead[0] = 136;             break;          case 'ping':             // first byte indicates FIN, Ping frame (10001001):             $frameHead[0] = 137;             break;          case 'pong':             // first byte indicates FIN, Pong frame (10001010):             $frameHead[0] = 138;             break;     }      // set mask and payload length (using 1, 3 or 9 bytes)     if ($payloadLength > 65535) {         $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8);         $frameHead[1] = ($masked === true) ? 255 : 127;         for ($i = 0; $i < 8; $i++) {             $frameHead[$i + 2] = bindec($payloadLengthBin[$i]);         }          // most significant bit MUST be 0 (close connection if frame too big)         if ($frameHead[2] > 127) {             $this->close(1004);             return false;         }     } elseif ($payloadLength > 125) {         $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8);         $frameHead[1] = ($masked === true) ? 254 : 126;         $frameHead[2] = bindec($payloadLengthBin[0]);         $frameHead[3] = bindec($payloadLengthBin[1]);     } else {         $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength;     }      // convert frame-head to string:     foreach (array_keys($frameHead) as $i) {         $frameHead[$i] = chr($frameHead[$i]);     }      if ($masked === true) {         // generate a random mask:         $mask = array();         for ($i = 0; $i < 4; $i++) {             $mask[$i] = chr(rand(0, 255));         }          $frameHead = array_merge($frameHead, $mask);     }     $frame = implode('', $frameHead);     // append payload to frame:     for ($i = 0; $i < $payloadLength; $i++) {         $frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];     }      return $frame; }  ?> 
like image 37
Rodislav Moldovan Avatar answered Sep 22 '22 13:09

Rodislav Moldovan