#php #websocket
Добрый день. Собственно такая проблема: есть веб сокет на Ratchet, к нему уже подрублен браузер который прекрасно с ним соединяется (в общем проблем с web socket - браузер нет), проблема возникла тогда когда я начал подключать к сокету php скрипт, сам скрипт к сокету подрубается и может от него получать данные, но вот обратно отправлять их на сокет он не может не как. Пробовал через fwrite и stream_socket_sendto, оба варианта не дали не какого результата. Код для подключения к сокету: $socket = stream_socket_client('tcp://localhost:8080', $errorNumber, $errorString, 1); stream_set_blocking($socket, 0); if (!$socket) { echo "{$errorString} ({$errorNumber})
\n"; } else { $header = "GET / HTTP/1.1\r\n" . "Host: localhost\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Key: tQXaRIOk4sOhgoq7SBs43g==\r\n" . "Sec-WebSocket-Version: 13\r\n\r\n"; fwrite($socket, $header); while (!feof($socket)) { $context = fgets($socket, 1024); echo($context); } fclose($socket); } Код самого сокет сервера на ratchet я приводить не буду он стандартный, все как в доке описано. PS помогите разобраться, а то уже вторые сутки бьюсь все не как не могу понять что я делаю не так, ведь в теории если приведенный мною скрипт может получать данные с сокета, то 100% он должен их и как то отправлять.
Ответы
Ответ 1
Вообщем если у кого возник такая проблема(ответ нашел на 4 странице в гугле в конце), то нужно сделать следующее(данный вариан решения проблемы подходит не только для symfony): setName('server:run') ->setDescription('Запускаем сокет.'); } protected function execute(InputInterface $input, OutputInterface $output) { $socket = stream_socket_client('tcp://localhost:8080', $errorNumber, $errorString, 1); if (!$socket) { echo "{$errorString} ({$errorNumber})
\n"; } else { $data = "first message"; $head = "GET / HTTP/1.1\r\n" . "Host: localhost\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Key: tQXaRIOk4sOhqwe7SBs43g==\r\n" . "Sec-WebSocket-Version: 13\r\n" . "Content-Length: ".strlen($data)."\r\n"."\r\n"; fwrite($socket, $head); $headers = fread($socket, 2000); echo $headers; fwrite($socket, $this->hybi10Encode($data)); $wsdata = fread($socket, 2000); var_dump($this->hybi10Decode($wsdata)); fclose($socket); /*fwrite($socket, $header); while (!feof($socket)) { $context = fgets($socket, 1024); echo($context); } fclose($socket);*/ } } private 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; } private 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; } }Ответ 2
А зачем сокеты? Не желаете ли использовать тот же cURL, который намного быстрее и безопаснее сокетов и file_get_contents(). cURL Upd 1: На недельке увидел просто шикарную библиотеку для сокетов - Socket.io. Написать серверную часть на Node.js, если это можно сделать на Вашем хостинге и т.п, и подключить прием по сокетам по ключам на Socket.io. Сегодня буду делать тестовую API. Пример выложу на гитхабе.
Комментариев нет:
Отправить комментарий