diff --git a/docs/Changelog.md b/docs/Changelog.md index f87b181..b1bbb47 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,7 @@ ### `3.1.0` * Server `getConnections()`, `getReadableConnections()`, `getWritableConnections()` (@sirn-se) + * `onHandshake(...)` listener (will deprecate `onConnect(...)`) (@sirn-se) ### `3.0.0` diff --git a/docs/Examples.md b/docs/Examples.md index b801202..e6faa59 100644 --- a/docs/Examples.md +++ b/docs/Examples.md @@ -61,7 +61,7 @@ $client ->addMiddleware(new PingResponder()) // Add ping interval middleware as heartbeat to keep connection open ->addMiddleware(new PingInterval(interval: 30)) - ->onConnect(function (Client $client, Connection $connection, ResponseInterface $response) { + ->onHandshake(function (Client $client, Connection $connection, RequestInterface $request, ResponseInterface $response) { // Initial message, typically some authorization or configuration // This will be called everytime the client connect or reconnect $client->text($initial_message); diff --git a/docs/Listener.md b/docs/Listener.md index 89ed815..6939ad9 100644 --- a/docs/Listener.md +++ b/docs/Listener.md @@ -40,13 +40,13 @@ $client_or_server These listeners are called when the Client or Server connects and disconnects. -* On Client, the `onConnect()` will receive a `Response` as last argument -* On Server, the `onConnect()` will receive a `ServerRequest` as last argument +* On Client, the `onHandshake()` will receive `Request` and `Response` as last arguments +* On Server, the `onHandshake()` will receive `ServerRequest` and `Response` as last arguments ```php $client_or_server - // Called when a connection is established - ->onConnect(function (WebSocket\Client|WebSocket\Server $client_or_server WebSocket\Connection $connection, Psr\Http\Message\ServerRequestInterface|Psr\Http\Message\ResponseInterface $request_or_respone) { + // Called when a connection and handshake established + ->onHandshake(function (WebSocket\Client|WebSocket\Server $client_or_server WebSocket\Connection $connection, Psr\Http\Message\RequestInterface|Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $respone) { // Act on connect }) // Called when a connection is closed diff --git a/docs/Migrate_2_3.md b/docs/Migrate_2_3.md index 7cdee0b..dd0fa36 100644 --- a/docs/Migrate_2_3.md +++ b/docs/Migrate_2_3.md @@ -1,10 +1,12 @@ [Documentation](Index.md) / Migration v2 -> v3 +# Websocket: Migration v2 -> v3 + Version 3.x has few changes compared to previous version. -# Breaking changes +## Breaking changes -## setLogger +### setLogger ```php Client->setLogger(LoggerInterface $logger): void @@ -17,7 +19,7 @@ This means method return can not be chained. The change makes v3 complient with `psr/log v3`. -## receive +### receive ```php Client->receive(): Message @@ -26,6 +28,6 @@ Client->receive(): Message The method no longer has `Message|null` as return type. It never returned `null` before, so only the method profile has changed. -# Extending +## Extending When extending classes in this repo, you might need to implement typed properties in child class. diff --git a/examples/echoserver.php b/examples/echoserver.php index 922f37b..3e0e93a 100644 --- a/examples/echoserver.php +++ b/examples/echoserver.php @@ -53,8 +53,8 @@ } echo "# Listening on port {$server->getPort()}\n"; - $server->onConnect(function ($server, $connection, $handshake) { - echo "> [{$connection->getRemoteName()}] Client connected {$handshake->getUri()}\n"; + $server->onHandshake(function ($server, $connection, $request, $response) { + echo "> [{$connection->getRemoteName()}] Client connected {$request->getUri()}\n"; })->onDisconnect(function ($server, $connection) { echo "> [{$connection->getRemoteName()}] Client disconnected\n"; })->onText(function ($server, $connection, $message) { diff --git a/examples/random_client.php b/examples/random_client.php index bae7fbd..7b2ca10 100644 --- a/examples/random_client.php +++ b/examples/random_client.php @@ -64,8 +64,8 @@ } echo "# Listening on {$options['uri']}\n"; - $client->onConnect(function ($client, $connection, $handshake) { - echo "> [{$connection->getRemoteName()}] Server connected {$handshake->getStatusCode()}\n"; + $client->onHandshake(function ($server, $connection, $request, $response) { + echo "> [{$connection->getRemoteName()}] Server connected {$response->getStatusCode()}\n"; })->onDisconnect(function ($client, $connection) { echo "> [{$connection->getRemoteName()}] Server disconnected\n"; })->onText(function ($client, $connection, $message) { diff --git a/examples/random_server.php b/examples/random_server.php index 79fd591..8c996aa 100644 --- a/examples/random_server.php +++ b/examples/random_server.php @@ -63,8 +63,8 @@ } echo "# Listening on port {$server->getPort()}\n"; - $server->onConnect(function ($server, $connection, $handshake) { - echo "> [{$connection->getRemoteName()}] Client connected {$handshake->getUri()}\n"; + $server->onHandshake(function ($server, $connection, $request, $response) { + echo "> [{$connection->getRemoteName()}] Client connected {$request->getUri()}\n"; })->onDisconnect(function ($server, $connection) { echo "> [{$connection->getRemoteName()}] Client disconnected\n"; })->onText(function ($server, $connection, $message) { diff --git a/src/Client.php b/src/Client.php index 08dcdfa..bffeafc 100644 --- a/src/Client.php +++ b/src/Client.php @@ -423,6 +423,12 @@ public function connect(): void return; } $this->logger->info("[client] Client connected to {$this->socketUri}"); + $this->dispatch('handshake', [ + $this, + $this->connection, + $this->connection->getHandshakeRequest(), + $this->connection->getHandshakeResponse(), + ]); $this->dispatch('connect', [$this, $this->connection, $response]); } diff --git a/src/Server.php b/src/Server.php index d8db0b4..f2f7d6b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -432,6 +432,12 @@ protected function acceptSocket(SocketServer $socket): void $request = $this->performHandshake($connection); $this->connections[$name] = $connection; $this->logger->info("[server] Accepted connection from {$name}."); + $this->dispatch('handshake', [ + $this, + $connection, + $connection->getHandshakeRequest(), + $connection->getHandshakeResponse(), + ]); $this->dispatch('connect', [$this, $connection, $request]); } catch (Exception $e) { if ($connection) { diff --git a/src/Trait/ListenerTrait.php b/src/Trait/ListenerTrait.php index 1d9e0bc..01c83b2 100644 --- a/src/Trait/ListenerTrait.php +++ b/src/Trait/ListenerTrait.php @@ -17,6 +17,7 @@ trait ListenerTrait { private array $listeners = []; + /* @todo: Deprecate and remove in v4 */ public function onConnect(Closure $closure): self { $this->listeners['connect'] = $closure; @@ -29,6 +30,12 @@ public function onDisconnect(Closure $closure): self return $this; } + public function onHandshake(Closure $closure): self + { + $this->listeners['handshake'] = $closure; + return $this; + } + public function onText(Closure $closure): self { $this->listeners['text'] = $closure; diff --git a/tests/suites/client/ClientTest.php b/tests/suites/client/ClientTest.php index 9ffacbc..02ce58b 100644 --- a/tests/suites/client/ClientTest.php +++ b/tests/suites/client/ClientTest.php @@ -32,6 +32,7 @@ ClientException }; use WebSocket\Http\{ + Request, Response }; use WebSocket\Test\MockStreamTrait; @@ -821,6 +822,13 @@ public function testListeners(): void $client = new Client('ws://localhost:8000/my/mock/path'); $client->setStreamFactory(new StreamFactory()); + $client->onHandshake(function ($client, $connection, $request, $response) { + $this->assertInstanceOf(Client::class, $client); + $this->assertInstanceOf(Connection::class, $connection); + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(Response::class, $response); + $this->assertTrue($client->isRunning()); + }); $client->onConnect(function ($client, $connection, $response) { $this->assertInstanceOf(Client::class, $client); $this->assertInstanceOf(Connection::class, $connection); @@ -959,7 +967,7 @@ public function testAlreadyStarted(): void $client = new Client('ws://localhost:8000/my/mock/path'); $client->setStreamFactory(new StreamFactory()); - $client->onConnect(function ($client, $connection, $request) { + $client->onHandshake(function ($client, $connection, $request, $response) { $client->start(); $client->stop(); }); diff --git a/tests/suites/server/ServerTest.php b/tests/suites/server/ServerTest.php index 3f43200..3cebf59 100644 --- a/tests/suites/server/ServerTest.php +++ b/tests/suites/server/ServerTest.php @@ -32,6 +32,7 @@ ServerException }; use WebSocket\Http\{ + Response, ServerRequest }; use WebSocket\Message\{ @@ -77,6 +78,12 @@ public function testListeners(): void $this->assertInstanceOf(Stringable::class, $server); $this->assertEquals('WebSocket\Server(closed)', "{$server}"); + $server->onHandshake(function ($server, $connection, $request, $response) { + $this->assertInstanceOf(Server::class, $server); + $this->assertInstanceOf(Connection::class, $connection); + $this->assertInstanceOf(ServerRequest::class, $request); + $this->assertInstanceOf(Response::class, $response); + }); $server->onConnect(function ($server, $connection, $request) { $this->assertInstanceOf(Server::class, $server); $this->assertInstanceOf(Connection::class, $connection); @@ -335,7 +342,7 @@ public function testDetachConnection(): void $server = new Server(8000); $server->setStreamFactory(new StreamFactory()); - $server->onConnect(function ($server, $connection, $request) { + $server->onHandshake(function ($server, $connection, $request, $response) { $connection->disconnect(); $server->stop(); }); @@ -388,7 +395,7 @@ public function testAlreadyStarted(): void $server = new Server(8000); $server->setStreamFactory(new StreamFactory()); - $server->onConnect(function ($server, $connection, $request) { + $server->onHandshake(function ($server, $connection, $request, $response) { $connection->disconnect(); $server->start(); $server->stop();