From f32897a854c2e5c4c351f3cb731cc3a8498fa0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Jensen?= Date: Sun, 30 Jun 2024 16:41:38 +0200 Subject: [PATCH] Server get*Connection methods --- docs/Changelog.md | 4 ++++ docs/Server.md | 20 ++++++++++++++++-- src/Server.php | 33 +++++++++++++++++++++++++++++- tests/README.md | 11 +++++----- tests/suites/server/ConfigTest.php | 8 ++++++++ tests/suites/server/ServerTest.php | 13 ++++++++++++ 6 files changed, 81 insertions(+), 8 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index ef1de37..f87b181 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -6,6 +6,10 @@ > PHP version `^8.1` +### `3.1.0` + + * Server `getConnections()`, `getReadableConnections()`, `getWritableConnections()` (@sirn-se) + ### `3.0.0` * Support `psr/log v3` (@sirn-se) diff --git a/docs/Server.md b/docs/Server.md index 632d7ac..a990892 100644 --- a/docs/Server.md +++ b/docs/Server.md @@ -49,7 +49,6 @@ echo "scheme: {$server->getScheme()}\n"; echo "timeout: {$server->getTimeout()}s\n"; echo "frame size: {$server->getFrameSize()}b\n"; echo "running: {$server->isRunning()}\n"; -echo "connections: {$server->getConnectionCount()}\n"; echo "ssl: {$server->isSsl()}\n"; ``` @@ -170,12 +169,29 @@ $server->start(); // Stop server - When called, server will no longer listen to incoming messages but will not disconnect clients $server->stop(); -//Disconnect server - Server will immediately stop and disconnect all clients without normal close procedure +// Disconnect server - Server will immediately stop and disconnect all clients without normal close procedure $server->disconnect(); ``` To shut down server in an orderly fashion, you should first close all connected clients. + +## Server operations + +```php +// Number of connected clients +$server->getConnectionCount(); + +// Get all current connections (may be in any state) +$server->getConnections(); + +// Get all readable connections +$server->getReadableConnections(); + +// Get all writable connections +$server->getWritableConnections(); +``` + ## Connection control The Connection instance have some additional functions, besides sending messages to client. diff --git a/src/Server.php b/src/Server.php index f51dcae..d8db0b4 100644 --- a/src/Server.php +++ b/src/Server.php @@ -212,6 +212,37 @@ public function getConnectionCount(): int return count($this->connections); } + /** + * Get currently connected clients. + * @return array Connections + */ + public function getConnections(): array + { + return $this->connections; + } + + /** + * Get currently readable clients. + * @return array Connections + */ + public function getReadableConnections(): array + { + return array_filter($this->connections, function (Connection $connection) { + return $connection->isReadable(); + }); + } + + /** + * Get currently writable clients. + * @return array Connections + */ + public function getWritableConnections(): array + { + return array_filter($this->connections, function (Connection $connection) { + return $connection->isWritable(); + }); + } + /** * Add a middleware. * @param WebSocket\Middleware\MiddlewareInterface $middleware @@ -304,7 +335,7 @@ public function start(): void if ($connection) { $connection->close($e->getCloseStatus(), $e->getMessage()); } - $this->logger->error("[server] sss {$e->getMessage()}"); + $this->logger->error("[server] {$e->getMessage()}"); $this->dispatch('error', [$this, $connection, $e]); } } diff --git a/tests/README.md b/tests/README.md index 0af2997..de0a3a8 100644 --- a/tests/README.md +++ b/tests/README.md @@ -14,15 +14,16 @@ make test ## Continuous integration -GitHub Actions are run on PHP versions `7.4`, `8.0`, `8.1` and `8.2`. +GitHub Actions are run on PHP versions `8.1`, `8.2`, `8.3` and `8.4`. -Code coverage by [Coveralls](https://coveralls.io/github/Textalk/websocket-php). +Code coverage by [Coveralls](https://coveralls.io/github/sirn-se/websocket-php). ## Test strategy -Test set up overloads various stream and socket functions, -and use "scripts" to define and mock input/output of these functions. +Uses the [phrity/net-mock](https://packagist.org/packages/phrity/net-mock) library to mock +stream operations, implementing `expect` before methods that uses stream interactions +are called. -This set up negates the dependency on running servers, +This set up negates the dependency on running actual servers, and allow testing various errors that might occur. diff --git a/tests/suites/server/ConfigTest.php b/tests/suites/server/ConfigTest.php index 5aba142..a2a9142 100644 --- a/tests/suites/server/ConfigTest.php +++ b/tests/suites/server/ConfigTest.php @@ -61,6 +61,9 @@ public function testServerDefaults(): void $this->assertEquals('tcp', $server->getScheme()); $this->assertFalse($server->isRunning()); $this->assertEquals(0, $server->getConnectionCount()); + $this->assertEmpty($server->getConnections()); + $this->assertEmpty($server->getReadableConnections()); + $this->assertEmpty($server->getWritableConnections()); $this->expectWsServerSetup(scheme: 'tcp', port: 8000); $this->expectStreamCollectionWaitRead()->addAssert(function ($method, $params) { @@ -119,6 +122,11 @@ public function testServerConfiguration(): void $this->assertEquals('ssl', $server->getScheme()); $this->assertFalse($server->isRunning()); $this->assertEquals(1, $server->getConnectionCount()); + $this->assertCount(1, $server->getConnections()); + $this->expectSocketStreamIsReadable(); + $this->assertCount(1, $server->getReadableConnections()); + $this->expectSocketStreamIsWritable(); + $this->assertCount(1, $server->getWritableConnections()); $this->expectSocketStreamIsConnected(); $this->expectSocketStreamClose(); diff --git a/tests/suites/server/ServerTest.php b/tests/suites/server/ServerTest.php index ddfee20..3f43200 100644 --- a/tests/suites/server/ServerTest.php +++ b/tests/suites/server/ServerTest.php @@ -466,6 +466,11 @@ public function testRunBadOpcodeException(): void // Should not have closed $this->assertEquals(1, $server->getConnectionCount()); + $this->assertCount(1, $server->getConnections()); + $this->expectSocketStreamIsReadable(); + $this->assertCount(1, $server->getReadableConnections()); + $this->expectSocketStreamIsWritable(); + $this->assertCount(1, $server->getWritableConnections()); $this->expectSocketStreamClose(); $this->expectSocketServerClose(); @@ -510,6 +515,9 @@ public function testRunConnectionClosedException(): void // Should be closed $this->assertEquals(0, $server->getConnectionCount()); + $this->assertEmpty($server->getConnections()); + $this->assertEmpty($server->getReadableConnections()); + $this->assertEmpty($server->getWritableConnections()); $this->expectSocketServerClose(); $server->disconnect(); @@ -551,6 +559,11 @@ public function testRunServerException(): void // Should not have closed $this->assertEquals(1, $server->getConnectionCount()); + $this->assertCount(1, $server->getConnections()); + $this->expectSocketStreamIsReadable(); + $this->assertCount(1, $server->getReadableConnections()); + $this->expectSocketStreamIsWritable(); + $this->assertCount(1, $server->getWritableConnections()); $this->expectSocketStreamClose(); $this->expectSocketServerClose();