From ac2c81f0be2cc0b1aea9345a3e11c82304bb0117 Mon Sep 17 00:00:00 2001 From: Simon Asika Date: Fri, 10 Nov 2023 17:06:00 +0800 Subject: [PATCH] Support open / close --- .../resources/servers/swoole_websocket.php | 57 ++++++++++--------- .../reactor/src/Swoole/Event/CloseEvent.php | 20 ++++++- .../reactor/src/Swoole/Event/MessageEvent.php | 9 +++ packages/reactor/src/Swoole/SwooleServer.php | 4 +- .../src/WebSocket/WebSocketRequest.php | 7 +++ 5 files changed, 68 insertions(+), 29 deletions(-) diff --git a/packages/reactor/resources/servers/swoole_websocket.php b/packages/reactor/resources/servers/swoole_websocket.php index f51fdcecc..eeb600dc2 100644 --- a/packages/reactor/resources/servers/swoole_websocket.php +++ b/packages/reactor/resources/servers/swoole_websocket.php @@ -140,8 +140,12 @@ function (OpenEvent $event) use ($app) { // Keep request in memory, so we can use this request cross processes. $app->rememberRequest($request); - // Run custom open() code. - $app->openConnection($request); + try { + // Run custom open() code. + $app->openConnection($request); + } catch (\Throwable $e) { + CliServerRuntime::handleThrowable($e); + } } ); @@ -160,8 +164,7 @@ function (OpenEvent $event) use ($app) { $server->onMessage( function (MessageEvent $event) use ($app) { // Get request object from memory - $request = $app->getRequest($event->getFd()) - ->withFrame($event->getFrame()); + $request = $event->getRequestFromMemory($app); try { $app->runContextByRequest($request); @@ -171,6 +174,29 @@ function (MessageEvent $event) use ($app) { } ); +/* + * -------------------------------------------------------------------------- + * Connection Close + * -------------------------------------------------------------------------- + * The event of connection closing. + * This event will release the objects which keeping in memory. + * To add custom close handler, put your code into WsApplication::started() + */ + +$server->onClose( + function (CloseEvent $event) use ($app) { + // Get request from memory and release it + $request = $event->getAndForgetRequest($app); + + try { + // Run custom close handler. + $app->closeConnection($request); + } catch (\Throwable $e) { + CliServerRuntime::handleThrowable($e); + } + } +); + /* * -------------------------------------------------------------------------- * Server Start @@ -197,29 +223,6 @@ function (StartEvent $event) use ($server, $app) { } ); -/* - * -------------------------------------------------------------------------- - * Connection Close - * -------------------------------------------------------------------------- - * The event of connection closing. - * This event will release the objects which keeping in memory. - * To add custom close handler, put your code into WsApplication::started() - */ - -$server->onClose( - function (CloseEvent $event) use ($app) { - // Get request from memory - $request = $app->getRequest($event->getFd()) - ->withFrame($event->createWocketFrame()); - - // Release request object from memory - $app->forgetRequest($event->getFd()); - - // Run custom close handler. - $app->closeConnection($request); - } -); - /* * -------------------------------------------------------------------------- * Boot Application diff --git a/packages/reactor/src/Swoole/Event/CloseEvent.php b/packages/reactor/src/Swoole/Event/CloseEvent.php index ab92c20ba..e9f0bdc90 100644 --- a/packages/reactor/src/Swoole/Event/CloseEvent.php +++ b/packages/reactor/src/Swoole/Event/CloseEvent.php @@ -7,6 +7,8 @@ use Windwalker\Event\AbstractEvent; use Windwalker\Reactor\WebSocket\WebSocketFrame; use Windwalker\Reactor\WebSocket\WebSocketFrameInterface; +use Windwalker\Reactor\WebSocket\WebSocketRequestInterface; +use Windwalker\WebSocket\Application\WsApplicationInterface; /** * The CloseEvent class. @@ -16,8 +18,24 @@ class CloseEvent extends AbstractEvent use ServerEventTrait; use TcpEventTrait; - public function createWocketFrame(): WebSocketFrameInterface + public function createWebSocketFrame(): WebSocketFrameInterface { return new WebSocketFrame($this->getFd()); } + + public function getRequestFromMemory(WsApplicationInterface $app): WebSocketRequestInterface + { + return $app->getRememberedRequest($this->getFd()) + ->withFrame($this->createWebSocketFrame()) + ->withMethod('CLOSE'); + } + + public function getAndForgetRequest(WsApplicationInterface $app): WebSocketRequestInterface + { + $request = $this->getRequestFromMemory($app); + + $app->forgetRequest($request->getFd()); + + return $request; + } } diff --git a/packages/reactor/src/Swoole/Event/MessageEvent.php b/packages/reactor/src/Swoole/Event/MessageEvent.php index e4fd0b831..071324997 100644 --- a/packages/reactor/src/Swoole/Event/MessageEvent.php +++ b/packages/reactor/src/Swoole/Event/MessageEvent.php @@ -6,6 +6,8 @@ use Windwalker\Event\AbstractEvent; use Windwalker\Reactor\WebSocket\WebSocketFrameInterface; +use Windwalker\Reactor\WebSocket\WebSocketRequestInterface; +use Windwalker\WebSocket\Application\WsApplicationInterface; /** * The MessageEvent class. @@ -42,4 +44,11 @@ public function getData(): string { return $this->frame->getData(); } + + public function getRequestFromMemory(WsApplicationInterface $app): WebSocketRequestInterface + { + return $app->getRememberedRequest($this->getFd()) + ->withFrame($this->getFrame()) + ->withMethod('MESSAGE'); + } } diff --git a/packages/reactor/src/Swoole/SwooleServer.php b/packages/reactor/src/Swoole/SwooleServer.php index 619903b45..5eeb5542d 100644 --- a/packages/reactor/src/Swoole/SwooleServer.php +++ b/packages/reactor/src/Swoole/SwooleServer.php @@ -805,7 +805,9 @@ function (Request $request, Response $response) { $port, 'Open', function (SwooleBaseServer $swooleServer, Request $swooleRequest) use ($server) { - $request = SwooleRequestFactory::createPsrSwooleRequest($swooleRequest); + $request = SwooleRequestFactory::createPsrSwooleRequest($swooleRequest) + ->withMethod('OPEN'); + $this->emit( OpenEvent::class, compact( diff --git a/packages/reactor/src/WebSocket/WebSocketRequest.php b/packages/reactor/src/WebSocket/WebSocketRequest.php index 64cfe1f9d..3d5751999 100644 --- a/packages/reactor/src/WebSocket/WebSocketRequest.php +++ b/packages/reactor/src/WebSocket/WebSocketRequest.php @@ -15,6 +15,13 @@ class WebSocketRequest extends ServerRequest implements WebSocketRequestInterfac protected mixed $parsedData = null; + protected array $allowMethods = [ + 'GET', + 'OPEN', + 'MESSAGE', + 'CLOSE' + ]; + public static function createFromFrame(WebSocketFrameInterface $frame): static { return (new static())->withFrame($frame);