PHP client Web socket to send messages PHP client Web socket to send messages codeigniter codeigniter

PHP client Web socket to send messages


If you are talking about connecting to your Websocket using Php, then YES, it is doable. There are a few libraries like Php WebSocket client or Websocket php that can connect to your websocket as a Client.

You can also check out this Websocket Client for an example.

Another Working Example without using any library and implementing the hybi10 frame encoding as per the specification:

$host = 'www.host.com';  // your websocket server$port = 443;$local = "http://localhost";  // url where this script runs | Client$data = '{"id": 2,"command": "server_info"}';  // data to be sent$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-Version: 13"."\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);fwrite($sock, hybi10Encode($data)) or die('error:'.$errno.':'.$errstr);$wsdata = fread($sock, 2000);fclose($sock);var_dump(hybi10Decode($wsdata));// hibi10 decoding of datafunction 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;}// hibi10 encoding of datafunction 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;}

Lastly, you can send your byte data as a JSON object by encoding it to base64 first. Check this SO Post to see how to do that. Hope this helps.


My unswer NO. You can not fully use the websocket client logick, using only the server part(for example php). Because the server side know anything about the browser. Server - receives a request and returns a static result. All magic in the browser is javascript. Javascript can dynamically listen all user events, post a query to server and insert a response from the server to the page. Websocket can not work without javascript in browser.This is WebSocket definition:

WebSockets are a bi-directional, full-duplex, persistent connection from a web browser to a server. Once a WebSocket connection is established the connection stays open until the client or server decides to close this connection. With this open connection, the client or server can send a message at any given time to the other. This makes web programming entirely event driven, not (just) user initiated. It is stateful. As well, at this time, a single running server application is aware of all connections, allowing you to communicate with any number of open connections at any given time.

The only thing you can do, is learn node js. It will allow you to write the browser (client) part and server part on one language - javascript. But however this will be different parts of application, and you will use different approaches, to program each part


It's not what you want but could help. You can use Redis as a middleware. Use Redis publish/subscribe message system.Redis publish/subscribe message system