Пример клиента WebSocket на PHP
Если клиент на javascript для WebSocket это весьма простая вещь, то на PHP чуточку сложнее. Готовых примеров в сети раз-два и обчелся. Вот пример одной из реализаций:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
$local = "http://грибовы.рф"; $data = "Скрипт обработки выбора фильтра абонентом"; $key="woeudhцукацук цук пупркеркеуенakcslerug;er"; $host=$row2["mysql_ip"]; $port = 8000; $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: asd245345235d6asd6as7d"."\r\n". "Content-Length: ".strlen($data)."\r\n"."\r\n"; $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)); //echo "--send\n"; $mess["key"]=$key; $mess["command"]="UpdateFilterContent"; fwrite($sock, hybi10Encode(json_encode($mess))) or die('error:'.$errno.':'.$errstr); //echo "--read\n"; $wsdata = fread($sock, 2000); //var_dump(hybi10Decode($wsdata)); fclose($sock); |
Вспомогательные функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
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; } |