getBody(); $location = $request['host'] . $request->getUrl(); $keynumb1 = (float) preg_replace('#[^0-9]#', '', $key1); $keynumb2 = (float) preg_replace('#[^0-9]#', '', $key2); $spaces1 = substr_count($key1, ' '); $spaces2 = substr_count($key2, ' '); if (0 === $spaces1 || 0 === $spaces2) { throw new Websocket\Exception\BadProtocol( 'Header Sec-WebSocket-Key1: %s or ' . 'Sec-WebSocket-Key2: %s is illegal.', 0, [$key1, $key2] ); } $part1 = pack('N', (int) ($keynumb1 / $spaces1)); $part2 = pack('N', (int) ($keynumb2 / $spaces2)); $challenge = $part1 . $part2 . $key3; $response = md5($challenge, true); $connection = $this->getConnection(); $connection->writeAll( 'HTTP/1.1 101 WebSocket Protocol Handshake' . "\r\n" . 'Upgrade: WebSocket' . "\r\n" . 'Connection: Upgrade' . "\r\n" . 'Sec-WebSocket-Origin: ' . $request['origin'] . "\r\n" . 'Sec-WebSocket-Location: ws://' . $location . "\r\n" . "\r\n" . $response . "\r\n" ); $connection->getCurrentNode()->setHandshake(SUCCEED); return; } /** * Read a frame. * * @return array */ public function readFrame() { $buffer = $this->getConnection()->read(2048); $length = strlen($buffer) - 2; if (empty($buffer)) { return [ 'fin' => 0x1, 'rsv1' => 0x0, 'rsv2' => 0x0, 'rsv3' => 0x0, 'opcode' => Websocket\Connection::OPCODE_CONNECTION_CLOSE, 'mask' => 0x0, 'length' => 0, 'message' => null ]; } return [ 'fin' => 0x1, 'rsv1' => 0x0, 'rsv2' => 0x0, 'rsv3' => 0x0, 'opcode' => Websocket\Connection::OPCODE_TEXT_FRAME, 'mask' => 0x0, 'length' => $length, 'message' => substr($buffer, 1, $length) ]; } /** * Write a frame. * * @param string $message Message. * @param int $opcode Opcode (useless here). * @param bool $end Whether it is the last frame of the message. * @param bool $mask Whether the message will be masked or not. * @return int */ public function writeFrame( $message, $opcode = -1, $end = true, $mask = false ) { return $this->getConnection()->writeAll( chr(0) . $message . chr(255) ); } /** * Send a message to a node (if not specified, current node). * * @param string $message Message. * @param int $opcode Opcode. * @param bool $end Whether it is the last frame of the message. * @param bool $mask Whether the message will be masked or not. * @return void */ public function send($message, $opcode = -1, $end = true, $mask = false) { $this->writeFrame($message); return; } /** * Close a specific node/connection. * * @param int $code Code (please, see * \Hoa\Websocket\Connection::CLOSE_* * constants). * @param string $reason Reason. * @param bool $mask Whether the message will be masked or not. * @return void */ public function close( $code = Websocket\Connection::CLOSE_NORMAL, $reason = null, $mask = false ) { return; } }