From fd854b28a95d886962c91d5287e1cf4d9d7977e8 Mon Sep 17 00:00:00 2001 From: Administrator Date: Mon, 15 Nov 2021 01:15:36 +0800 Subject: [PATCH] 1 --- Websocket/Server.php | 109 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Websocket/Server.php diff --git a/Websocket/Server.php b/Websocket/Server.php new file mode 100644 index 0000000..e9edbff --- /dev/null +++ b/Websocket/Server.php @@ -0,0 +1,109 @@ +server->start(); + } + + + /** + * @param string $Host + * @param int $Port + * @param bool $isSsl + * @param array $settings + */ + public function initCore(string $Host, int $Port, bool $isSsl, array $settings) + { + $this->server = new CoroutineServer($Host, $Port, $isSsl); + $this->server->set($settings['setting'] ?? []); + + $this->server->handle('/', function (Request $request, Response $response) { + $class = new \stdClass(); + if ($class instanceof OnHandshakeInterface) { + $class->onHandshake($request, $response); + } else if ($class instanceof OnOpenInterface) { + $response->upgrade(); + $class->onOpen($this->server, $request); + } + if (!($class instanceof OnMessageInterface)) { + $response->setStatusCode(200); + $response->end(); + } else { + $this->recover($class, $response); + } + }); + } + + + /** + * @param OnCloseInterface|OnMessageInterface $class + * @param Response $response + * @return bool + * @throws Exception + */ + private function recover(OnCloseInterface|OnMessageInterface $class, Response $response): bool + { + $frame = $response->recv(); + if ($frame === '' || $frame === FALSE) { + return $this->onClose($class, $response); + } + if ($frame->data == 'close' || get_class($frame) === CloseFrame::class) { + return $this->onClose($class, $response); + } + $class->onMessage($this->server, $frame); + return $this->recover($class, $response); + } + + + /** + * @param OnCloseInterface|OnMessageInterface $class + * @param Response $response + * @return bool + * @throws Exception + */ + private function onClose(OnCloseInterface|OnMessageInterface $class, Response $response): bool + { + if (!($close = $response->close())) { + Kiri::getDi()->get(Logger::class)->warning('close websocket fail.'); + } + $class->onClose($this->server, $response->fd); + return $close; + } + + + /** + * @return CoroutineServer + */ + public function getServer(): CoroutineServer + { + return $this->server; + } + +} \ No newline at end of file