diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 3ca249c..2e02b83 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -17,12 +17,12 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' + php-version: '8.2' extensions: openswoole, pcov - name: Validate composer.json and composer.lock run: composer validate - + - name: Cache Composer packages id: composer-cache uses: actions/cache@v2 diff --git a/README.md b/README.md index 3743401..ef8e852 100644 --- a/README.md +++ b/README.md @@ -31,10 +31,9 @@ Once installed, the following example shows how it works to use this package. ```php use Kanata\ConveyorServerClient\Client; -use WebSocket\Client as WsClient; $options = [ - 'onMessageCallback' => function(WsClient $currentClient, string $message) { + 'onMessageCallback' => function(Client $currentClient, string $message) { echo 'Message received: ' . $message . PHP_EOL; }, ]; @@ -140,6 +139,22 @@ This package has the following options (showing its respective defaults): ] ``` +This is this package's Conveyor Client interface: + +```php +namespace Kanata\ConveyorServerClient; + +use WebSocket\Client; + +interface ClientInterface +{ + public function connect(): void; + public function getClient(): ?Client; + public function close(): void; + public function send(string $message): void; +} +``` + ## Author 👤 **Savio Resende** diff --git a/composer.json b/composer.json index fde88db..536ddd7 100644 --- a/composer.json +++ b/composer.json @@ -14,14 +14,15 @@ } }, "require": { - "php": "^8", + "php": "^8.2", "textalk/websocket": "^1.5" }, "require-dev": { "phpunit/phpunit": "^9.5", "codedungeon/phpunit-result-printer": "^0.32.0", - "openswoole/ide-helper": "^4.11", - "kanata-php/socket-conveyor": "^1.1" + "openswoole/ide-helper": "^22.0", + "kanata-php/socket-conveyor": "^1.1", + "openswoole/core": "^22.1" }, "scripts": { "test": [ diff --git a/composer.lock b/composer.lock index 4cdb1c0..4207e93 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,245 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6c983b845135550c7ca6577accb3bece", + "content-hash": "cdccd30033fa456072a959172921be4a", "packages": [ + { + "name": "openswoole/core", + "version": "22.1.4", + "source": { + "type": "git", + "url": "https://github.com/openswoole/core.git", + "reference": "f21d58a74e271e7655b157f8e5b5f8dbf6649425" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/openswoole/core/zipball/f21d58a74e271e7655b157f8e5b5f8dbf6649425", + "reference": "f21d58a74e271e7655b157f8e5b5f8dbf6649425", + "shasum": "" + }, + "require": { + "ext-openswoole": ">=22.0", + "php": ">=7.4", + "psr/http-message": "^1.0", + "psr/http-server-middleware": "^1.0.0" + }, + "require-dev": { + "ext-curl": "*", + "ext-sockets": "*", + "friendsofphp/php-cs-fixer": "^3.6", + "openswoole/ide-helper": "^22.0", + "php-http/psr7-integration-tests": "^1.1", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-mysqli": "*", + "ext-pdo": "*", + "ext-redis": "Required to use redis database, and the required version is greater than or equal to 3.1.3" + }, + "type": "library", + "autoload": { + "files": [ + "src/Coroutine/functions.php" + ], + "psr-4": { + "OpenSwoole\\Core\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "OpenSwoole Group", + "email": "hello@openswoole.com" + } + ], + "description": "Openswoole core library", + "homepage": "https://openswoole.com", + "keywords": [ + "http", + "http2", + "mqtt", + "openswoole", + "php", + "tcp", + "websocket" + ], + "support": { + "docs": "https://openswoole.com/docs", + "issues": "https://github.com/openswoole/openswoole/issues", + "pull-request": "https://github.com/openswoole/openswoole/pulls", + "source": "https://github.com/openswoole/openswoole" + }, + "time": "2023-05-01T19:12:29+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + }, + { + "name": "psr/http-server-handler", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "support": { + "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" + }, + "time": "2023-04-10T20:06:20+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" + }, + "time": "2023-04-11T06:14:47+00:00" + }, { "name": "psr/log", "version": "3.0.0", @@ -628,23 +865,24 @@ }, { "name": "openswoole/ide-helper", - "version": "4.11.5", + "version": "22.0.1", "source": { "type": "git", "url": "https://github.com/openswoole/ide-helper.git", - "reference": "380827747c30890cdafbf9aa5ae34d9c7bbeb9db" + "reference": "43fc13f3cc3212784822103efeec82829f6f22f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/openswoole/ide-helper/zipball/380827747c30890cdafbf9aa5ae34d9c7bbeb9db", - "reference": "380827747c30890cdafbf9aa5ae34d9c7bbeb9db", + "url": "https://api.github.com/repos/openswoole/ide-helper/zipball/43fc13f3cc3212784822103efeec82829f6f22f5", + "reference": "43fc13f3cc3212784822103efeec82829f6f22f5", "shasum": "" }, "require": { + "ext-openswoole": ">=22.0", "php": ">=7.4" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.3" + "friendsofphp/php-cs-fixer": "^3.6" }, "type": "library", "notification-url": "https://packagist.org/downloads/", @@ -653,16 +891,16 @@ ], "authors": [ { - "name": "Open Swoole Group", + "name": "OpenSwoole Group", "email": "hello@openswoole.com" } ], - "description": "IDE help files for Open Swoole.", + "description": "IDE helper for OpenSwoole.", "support": { "issues": "https://github.com/openswoole/ide-helper/issues", - "source": "https://github.com/openswoole/ide-helper/tree/4.11.5" + "source": "https://github.com/openswoole/ide-helper/tree/22.0.1" }, - "time": "2022-07-24T09:46:27+00:00" + "time": "2023-02-05T22:27:37+00:00" }, { "name": "phar-io/manifest", @@ -2440,8 +2678,8 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8" + "php": "^8.2" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Client.php b/src/Client.php index 8cd5a71..b93808c 100644 --- a/src/Client.php +++ b/src/Client.php @@ -3,10 +3,11 @@ namespace Kanata\ConveyorServerClient; use Exception; +use WebSocket\BadOpcodeException; use WebSocket\Client as WsClient; use WebSocket\TimeoutException; -class Client +class Client implements ClientInterface { protected ?WsClient $client; @@ -95,7 +96,12 @@ public function __construct(array $options) $this->reconnectionInterval = $options['reconnectionInterval'] ?? 2; } - public function connect() + public function getClient(): ?WsClient + { + return $this->client; + } + + public function connect(): void { try { $this->handleClientConnection(); @@ -123,7 +129,26 @@ public function connect() } } - protected function handleDisconnection() + /** + * @throws BadOpcodeException + */ + public function send(string $message): void + { + $this->client->send(json_encode([ + 'action' => 'broadcast-action', + 'data' => $message, + ])); + } + + /** + * @throws BadOpcodeException + */ + public function sendRaw(string $message): void + { + $this->client->send($message); + } + + protected function handleDisconnection(): void { if (null === $this->onDisconnectCallback) { return; @@ -131,12 +156,12 @@ protected function handleDisconnection() call_user_func( $this->onDisconnectCallback, - $this->client, + $this, $this->reconnectionAttemptsCount ); } - protected function handleClientConnection() + protected function handleClientConnection(): void { $this->client = new WsClient( uri: $this->protocol . '://' . $this->uri . ':' . $this->port . '/' . $this->query, @@ -151,11 +176,11 @@ protected function handleClientConnection() if (null === $this->onMessageCallback) { continue; } - call_user_func($this->onMessageCallback, $this->client, $message); + call_user_func($this->onMessageCallback, $this, $message); } } - protected function handleChannelConnection() + protected function handleChannelConnection(): void { if (null === $this->channel) { return; @@ -167,7 +192,7 @@ protected function handleChannelConnection() ])); } - protected function handleListeners() + protected function handleListeners(): void { if (null === $this->listen) { return; @@ -181,16 +206,16 @@ protected function handleListeners() } } - protected function connectionReady() + protected function connectionReady(): void { if (null === $this->onReadyCallback) { return; } - call_user_func($this->onReadyCallback, $this->client); + call_user_func($this->onReadyCallback, $this); } - public function close() + public function close(): void { $this->client->close(); $this->client = null; diff --git a/src/ClientInterface.php b/src/ClientInterface.php new file mode 100644 index 0000000..894e6d6 --- /dev/null +++ b/src/ClientInterface.php @@ -0,0 +1,14 @@ + 8585, - 'onReadyCallback' => function(WsClient $currentClient) { - $currentClient->send('message-sent'); - }, - 'onMessageCallback' => function(WsClient $currentClient, string $message) use ($worker) { + 'channel' => 'sample-channel', + 'onMessageCallback' => function(Client $currentClient, string $message) use ($worker) { $worker->write($message); }, ]); $client->connect(); }); + $process2 = new Process(function(Process $worker) { + $client2 = new Client([ + 'port' => 8585, + 'channel' => 'sample-channel', + 'onReadyCallback' => function(Client $currentClient) use ($worker) { + $currentClient->send('message-sent'); + }, + ]); + $client2->connect(); + }); + $pid = $process->start(); + $pid2 = $process2->start(); $result = $process->read(); Process::kill($pid); + Process::kill($pid2); $this->assertEquals( 'message-sent', @@ -78,7 +92,7 @@ public function test_can_connect_to_channel() $client = new Client([ 'port' => 8585, 'channel' => 'sample-channel', - 'onMessageCallback' => function(WsClient $currentClient, string $message) use ($worker) { + 'onMessageCallback' => function(Client $currentClient, string $message) use ($worker) { $worker->write($message); }, 'timeout' => 1, @@ -95,11 +109,8 @@ public function test_can_connect_to_channel() $client = new Client([ 'port' => 8585, 'channel' => 'sample-channel', - 'onReadyCallback' => function(WsClient $currentClient) { - $currentClient->send(json_encode([ - 'action' => BroadcastAction::ACTION_NAME, - 'data' => 'message-sent', - ])); + 'onReadyCallback' => function(Client $currentClient) { + $currentClient->send('message-sent'); }, 'timeout' => 1, ]); @@ -136,7 +147,7 @@ public function test_can_listen_specific_actions() 'port' => 8585, 'channel' => 'sample-channel', 'listen' => [SecondaryBroadcastAction::ACTION_NAME], - 'onMessageCallback' => function(WsClient $currentClient, string $message) use ($worker) { + 'onMessageCallback' => function(Client $currentClient, string $message) use ($worker) { $worker->write($message); }, 'timeout' => 1, @@ -154,7 +165,7 @@ public function test_can_listen_specific_actions() 'port' => 8585, 'channel' => 'sample-channel', 'listen' => [BroadcastAction::ACTION_NAME], - 'onMessageCallback' => function (WsClient $currentClient, string $message) use ($worker) { + 'onMessageCallback' => function (Client $currentClient, string $message) use ($worker) { $worker->write($message); }, 'timeout' => 1, @@ -171,8 +182,8 @@ public function test_can_listen_specific_actions() $client = new Client([ 'port' => 8585, 'channel' => 'sample-channel', - 'onReadyCallback' => function(WsClient $currentClient) { - $currentClient->send(json_encode([ + 'onReadyCallback' => function(Client $currentClient) { + $currentClient->sendRaw(json_encode([ 'action' => SecondaryBroadcastAction::ACTION_NAME, 'data' => 'message-sent', ])); @@ -219,10 +230,10 @@ public function test_can_reconnect() $process = new Process(function(Process $worker) { $client = new Client([ 'port' => 8585, - 'onReadyCallback' => function(WsClient $currentClient) { - $currentClient->send('message-sent'); + 'onReadyCallback' => function(Client $currentClient) { + $currentClient->sendRaw('message-sent'); }, - 'onMessageCallback' => function(WsClient $currentClient, string $message) use ($worker) { + 'onMessageCallback' => function(Client $currentClient, string $message) use ($worker) { $worker->write($message); }, 'reconnect' => true, @@ -262,7 +273,7 @@ public function test_disconnection_callback() $process = new Process(function(Process $worker) { $client = new Client([ 'port' => 8585, - 'onDisconnectCallback' => function(WsClient $currentClient, $attemptsCount) use ($worker) { + 'onDisconnectCallback' => function(Client $currentClient, $attemptsCount) use ($worker) { $worker->write('disconnection-callbacl'); } ]); @@ -276,4 +287,4 @@ public function test_disconnection_callback() $this->assertEquals('disconnection-callbacl', $result); } -} \ No newline at end of file +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 951080e..0114017 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -36,4 +36,4 @@ protected function stopWsServer() { Process::kill($this->serverProcessPid); } -} \ No newline at end of file +}