application = $application; parent::__construct($host, $port, $mode, $sock_type); } /** * @param array $settings * @param null $pool * @param array $events * @param array $config * @return mixed|void * @throws NotFindClassException * @throws ReflectionException * @throws Exception */ public function set(array $settings, $pool = null, $events = [], $config = []) { parent::set($settings); Snowflake::get()->set(WebSocket::class, $this); Snowflake::get()->set(Pool::class, $pool); ServerManager::set($this, $settings, $this->application, $events, $config); } /** * @param Server $server * @param Frame $frame * @throws */ public function onMessage(Server $server, Frame $frame) { try { $event = Snowflake::get()->event; if ($event->exists(Event::SERVER_MESSAGE)) { $event->trigger(Event::SERVER_MESSAGE, [$server, $frame]); return; } if ($frame->opcode == 0x08) { return; } $json = json_decode($frame->data, true); $manager = Snowflake::get()->annotation; $manager->runWith($this->getName($json), [$frame->fd, $server]); } catch (Exception $exception) { // $this->error($exception->getMessage(), __METHOD__, __FILE__); // $this->addError($exception->getMessage()); } finally { $event = Snowflake::get()->event; $event->trigger(Event::EVENT_AFTER_REQUEST); Logger::insert(); } } /** * @param $json * @return string */ private function getName($json) { return 'WEBSOCKET:MESSAGE:' . $json['route']; } /** * @param SRequest $request * @param SResponse $response * @return bool * @throws Exception */ protected function connect($request, $response) { $manager = Snowflake::get()->event; if ($manager->exists(Event::SERVER_HANDSHAKE)) { return $manager->trigger(Event::SERVER_HANDSHAKE, [$request, $response]); } $response->status(502); $response->end(); return true; } /** * @param SRequest $request * @param SResponse $response * @return bool|string * @throws Exception */ public function onHandshake(SRequest $request, SResponse $response) { /** @var Server $server */ $secWebSocketKey = $request->header['sec-websocket-key']; $patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#'; if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) { return false; } $key = base64_encode(sha1( $request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE )); $headers = [ 'Upgrade' => 'websocket', 'Connection' => 'Upgrade', 'Sec-websocket-Accept' => $key, 'Sec-websocket-Version' => '13', ]; if (isset($request->header['sec-websocket-protocol'])) { $headers['Sec-websocket-Protocol'] = $request->header['sec-websocket-protocol']; } foreach ($headers as $key => $val) { $response->header($key, $val); } if (isset($request->get['debug']) && $request->get['debug'] == 'test') { $response->status(101); $response->end(); return true; } else { return $this->connect($request, $response); } } /** * @param Server $server * @param int $fd * @throws Exception */ public function onClose(Server $server, int $fd) { $event = Snowflake::get()->event; try { if ($event->exists(Event::SERVER_CLOSE)) { $event->trigger(Event::SERVER_CLOSE, [$fd]); } } catch (\Throwable $exception) { // $this->addError($exception->getMessage()); } finally { $event->trigger(Event::RELEASE_ALL); Logger::insert(); } } }