From 31596792b73630287aba611a9cf583dea2d3893f Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Fri, 28 Aug 2026 13:19:32 +0530 Subject: [PATCH 1/3] refactor: remove connection tracking from websocket library Drop getConnections() from Adapter, Server, Swoole, and Workerman, and remove Swoole's private self::$connections mirror. Tracking the set of live fds belongs to the calling layer, not the transport library. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01245mLhHWfmjZejiua8wvMP --- src/WebSocket/Adapter.php | 7 ------- src/WebSocket/Adapter/Swoole.php | 13 ------------- src/WebSocket/Adapter/Workerman.php | 5 ----- src/WebSocket/Server.php | 10 ---------- 4 files changed, 35 deletions(-) diff --git a/src/WebSocket/Adapter.php b/src/WebSocket/Adapter.php index 540e8e3..b8fa8c0 100644 --- a/src/WebSocket/Adapter.php +++ b/src/WebSocket/Adapter.php @@ -122,11 +122,4 @@ abstract public function setWorkerNumber(int $num): self; * @return mixed */ abstract public function getNative(): mixed; - - /** - * Returns all connections. - * - * @return array - */ - abstract public function getConnections(): array; } diff --git a/src/WebSocket/Adapter/Swoole.php b/src/WebSocket/Adapter/Swoole.php index 15af799..fc891e4 100644 --- a/src/WebSocket/Adapter/Swoole.php +++ b/src/WebSocket/Adapter/Swoole.php @@ -16,10 +16,6 @@ class Swoole extends Adapter protected string $host; protected int $port; - /** - * @var array - */ - private static array $connections = []; public function __construct(string $host = '0.0.0.0', int $port = 80) { @@ -103,8 +99,6 @@ public function onWorkerStop(callable $callback): Adapter public function onOpen(callable $callback): self { $this->server->on('open', function (Server $server, Request $request) use ($callback) { - self::$connections[$request->fd] = true; - call_user_func($callback, $request->fd, $request); }); @@ -123,8 +117,6 @@ public function onMessage(callable $callback): self public function onClose(callable $callback): self { $this->server->on('close', function (Server $server, int $fd) use ($callback) { - unset(self::$connections[$fd]); - call_user_func($callback, $fd); }); @@ -165,9 +157,4 @@ public function getNative(): Server { return $this->server; } - - public function getConnections(): array - { - return array_keys(self::$connections); - } } diff --git a/src/WebSocket/Adapter/Workerman.php b/src/WebSocket/Adapter/Workerman.php index b95234f..1f510a9 100644 --- a/src/WebSocket/Adapter/Workerman.php +++ b/src/WebSocket/Adapter/Workerman.php @@ -155,9 +155,4 @@ public function getNative(): Worker { return $this->server; } - - public function getConnections(): array - { - return array_keys(TcpConnection::$connections); - } } diff --git a/src/WebSocket/Server.php b/src/WebSocket/Server.php index 984eb34..795ef8c 100644 --- a/src/WebSocket/Server.php +++ b/src/WebSocket/Server.php @@ -214,16 +214,6 @@ public function onRequest(callable $callback): self return $this; } - /** - * Returns all connections. - * - * @return array - */ - public function getConnections(): array - { - return $this->adapter->getConnections(); - } - /** * Register callback. Will be executed when error occurs. * From 9efcc881cafbbe81b54dcf2d050d29765c2ecfb7 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Fri, 28 Aug 2026 13:19:38 +0530 Subject: [PATCH 2/3] test: track connections in server stubs instead of getConnections() The test servers now maintain their own $connections set in onOpen/onClose and use it for broadcast and the /info count, replacing the removed $server->getConnections(). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01245mLhHWfmjZejiua8wvMP --- tests/servers/Swoole/server.php | 17 +++++++++++------ tests/servers/Workerman/server.php | 17 +++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/tests/servers/Swoole/server.php b/tests/servers/Swoole/server.php index 54c88d1..fd80cea 100644 --- a/tests/servers/Swoole/server.php +++ b/tests/servers/Swoole/server.php @@ -11,6 +11,9 @@ $server = new WebSocket\Server($adapter); +/** @var array $connections */ +$connections = []; + $server ->onWorkerStart(function (int $workerId) { echo 'worker started ', $workerId, PHP_EOL; @@ -18,13 +21,15 @@ ->onWorkerStop(function (int $workerId) { echo "worker stopped ", $workerId, PHP_EOL; }) - ->onOpen(function (int $connection, Request $request) { + ->onOpen(function (int $connection, Request $request) use (&$connections) { + $connections[$connection] = true; echo 'connected ', $connection, PHP_EOL; }) - ->onClose(function (int $connection) { + ->onClose(function (int $connection) use (&$connections) { + unset($connections[$connection]); echo 'disconnected ', $connection, PHP_EOL; }) - ->onMessage(function (int $connection, string $message) use ($server) { + ->onMessage(function (int $connection, string $message) use ($server, &$connections) { echo $message, PHP_EOL; switch ($message) { @@ -35,7 +40,7 @@ $server->send([$connection], 'ping'); break; case 'broadcast': - $server->send($server->getConnections(), 'broadcast'); + $server->send(array_keys($connections), 'broadcast'); break; case 'disconnect': $server->send([$connection], 'disconnect'); @@ -43,7 +48,7 @@ break; } }) - ->onRequest(function (Request $request, Response $response) use ($server) { + ->onRequest(function (Request $request, Response $response) use ($server, &$connections) { echo 'HTTP request received: ', $request->server['request_uri'], PHP_EOL; if ($request->server['request_uri'] === '/health') { @@ -55,7 +60,7 @@ $response->status(200); $response->end(json_encode([ 'server' => 'Swoole WebSocket', - 'connections' => count($server->getConnections()), + 'connections' => count($connections), 'timestamp' => time() ])); } else { diff --git a/tests/servers/Workerman/server.php b/tests/servers/Workerman/server.php index 3333300..c83aaa2 100644 --- a/tests/servers/Workerman/server.php +++ b/tests/servers/Workerman/server.php @@ -11,6 +11,9 @@ $server = new WebSocket\Server($adapter); +/** @var array $connections */ +$connections = []; + $server ->onWorkerStart(function (int $workerId) { echo 'worker started ', $workerId, PHP_EOL; @@ -18,13 +21,15 @@ ->onWorkerStop(function (int $workerId) { echo "worker stopped ", $workerId, PHP_EOL; }) - ->onOpen(function (int $connection, array $request) { + ->onOpen(function (int $connection, array $request) use (&$connections) { + $connections[$connection] = true; echo 'connected ', $connection, PHP_EOL; }) - ->onClose(function (int $connection) { + ->onClose(function (int $connection) use (&$connections) { + unset($connections[$connection]); echo 'disconnected ', $connection, PHP_EOL; }) - ->onMessage(function (int $connection, string $message) use ($server) { + ->onMessage(function (int $connection, string $message) use ($server, &$connections) { echo $message, PHP_EOL; switch ($message) { @@ -35,7 +40,7 @@ $server->send([$connection], 'ping'); break; case 'broadcast': - $server->send($server->getConnections(), 'broadcast'); + $server->send(array_keys($connections), 'broadcast'); break; case 'disconnect': $server->send([$connection], 'disconnect'); @@ -43,7 +48,7 @@ break; } }) - ->onRequest(function (TcpConnection $connection, Request $request) use ($server) { + ->onRequest(function (TcpConnection $connection, Request $request) use ($server, &$connections) { $path = $request->path(); if (!is_string($path)) { throw new \Exception('Invalid path ' . $path . ' for request: ' . json_encode($request, JSON_PRETTY_PRINT)); @@ -61,7 +66,7 @@ 'Connection: close' . "\r\n\r\n" . json_encode([ 'server' => 'Workerman WebSocket', - 'connections' => count($server->getConnections()), + 'connections' => count($connections), 'timestamp' => time() ])); } else { From 2a61752d6fee657e3d9b0046ea6e6e642c285d6f Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Fri, 28 Aug 2026 13:21:46 +0530 Subject: [PATCH 3/3] test: drop unused $server from onRequest closures phpstan (level max) flagged the $server use as unused after the /info count switched from $server->getConnections() to the local $connections set. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01245mLhHWfmjZejiua8wvMP --- tests/servers/Swoole/server.php | 2 +- tests/servers/Workerman/server.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/servers/Swoole/server.php b/tests/servers/Swoole/server.php index fd80cea..59dca4d 100644 --- a/tests/servers/Swoole/server.php +++ b/tests/servers/Swoole/server.php @@ -48,7 +48,7 @@ break; } }) - ->onRequest(function (Request $request, Response $response) use ($server, &$connections) { + ->onRequest(function (Request $request, Response $response) use (&$connections) { echo 'HTTP request received: ', $request->server['request_uri'], PHP_EOL; if ($request->server['request_uri'] === '/health') { diff --git a/tests/servers/Workerman/server.php b/tests/servers/Workerman/server.php index c83aaa2..ee3e8e0 100644 --- a/tests/servers/Workerman/server.php +++ b/tests/servers/Workerman/server.php @@ -48,7 +48,7 @@ break; } }) - ->onRequest(function (TcpConnection $connection, Request $request) use ($server, &$connections) { + ->onRequest(function (TcpConnection $connection, Request $request) use (&$connections) { $path = $request->path(); if (!is_string($path)) { throw new \Exception('Invalid path ' . $path . ' for request: ' . json_encode($request, JSON_PRETTY_PRINT));