php-websocket-rpc / rpc-client
Async RPC client over WebSocket using amphp and msgpack
dev-main
2026-05-20 12:24 UTC
Requires
- php: >=8.5
- ext-msgpack: *
- amphp/amp: ^3
- amphp/websocket-client: ^2
- friendsofphp/proxy-manager-lts: ^1.0
- php-websocket-rpc/rpc: *
Requires (Dev)
- phpunit/phpunit: ^11
This package is auto-updated.
Last update: 2026-05-20 12:24:41 UTC
README
Async RPC client over WebSocket using amphp and msgpack.
Install
composer require php-websocket-rpc/rpc-client
Requires PHP 8.5+, ext-msgpack, and the amphp ecosystem.
Quick Start
use PhpWebsocketRpc\RpcClient\Client\RpcClient; $client = RpcClient::connect('ws://127.0.0.1:9502/rpc'); // ─── Typed request/response ─── $response = $client->call(new MathDivideRequest(x: 10, y: 2))->await(); echo $response->result; // 5 // ─── Fire-and-forget notification ─── $client->notify(new LogMessage(text: 'Hello!')); // ─── Using contract proxies ─── $math = $client->createProxy(MathService::class); $result = $math->add(10, 5); // call/response echo $result; // 15 $math->log('Hello!'); // notification foreach ($math->count(10) as $value) { // streaming echo $value; } $math->onEvent(function (string $event) { // subscribe echo "Got: $event"; }); $chat->send('Hello!'); // publish
Authentication
Authenticating
Use the built-in AuthService contract to authenticate:
use PhpWebsocketRpc\Rpc\Contract\AuthService; use PhpWebsocketRpc\Rpc\Auth\User; $auth = $client->createProxy(AuthService::class); $user = $auth->authenticate('your-token-here'); // $user is a User object (implements WebsocketUserInterface) echo $user->id; // user identifier echo $user->roles; // ['customer', 'admin']
Handling Auth Errors
use PhpWebsocketRpc\Rpc\Exception\AuthenticationException; use PhpWebsocketRpc\Rpc\Exception\AuthorizationException; try { $user = $auth->authenticate('invalid-token'); } catch (AuthenticationException $e) { echo $e->getRpcCode(); // -32010 echo $e->getMessage(); // 'Invalid or expired token' } try { $chat->deleteMessage('msg-1'); // requires admin role } catch (AuthorizationException $e) { echo $e->getRpcCode(); // -32011 echo $e->getMessage(); // 'Requires one of roles: admin...' } // Generic catch for all RPC errors use PhpWebsocketRpc\Rpc\Exception\RpcDispatchException; try { $result = $math->add(10, 5); } catch (RpcDispatchException $e) { echo $e->getRpcCode(); // e.g. -32601 (METHOD_NOT_FOUND) }
Logout
$auth->logout(); // clears auth state for this connection
Features
- Typed RPC calls — send typed payloads, receive typed responses
- Contract proxies —
createProxy()generates a dynamic proxy from any interface usingproxy-manager-lts - 5 patterns — call/response, notification, streaming, subscribe, publish
- Authentication — built-in
AuthServicecontract with typed exceptions - Fire-and-forget — notifications with no response
- Stream subscriptions — async iterables for streaming data (supports
foreach) - Publish/Subscribe — named channels with
#[RpcSubscribe]/#[RpcPublish] - Middleware — client-side middleware pipeline
- Retry support —
RetryableRpcClientwraps any client with configurable retry strategy
Contract Proxies
Define a shared interface:
interface MathService { public function add(int $a, int $b): int; public function mul(int $a, int $b): int; }
Use it transparently:
$math = $client->createProxy(MathService::class); $sum = $math->add(10, 5); // returns 15 — no boilerplate
The proxy is generated by friendsofphp/proxy-manager-lts using NullObjectFactory + AccessInterceptorValueHolderFactory — no eval() or runtime code generation.
Key Classes
| Class | Purpose |
|---|---|
PhpWebsocketRpc\RpcClient\Client\RpcClient |
Main client — connect, call, notify, subscribe, publish |
PhpWebsocketRpc\RpcClient\Client\ContractProxyFactory |
Generates dynamic proxies from interfaces |
PhpWebsocketRpc\RpcClient\Client\PendingRequestStore |
Tracks in-flight requests |
PhpWebsocketRpc\RpcClient\Client\SubscriptionManager |
Manages active stream subscriptions |
PhpWebsocketRpc\RpcClient\Client\RetryableRpcClient |
Client with automatic retry |
PhpWebsocketRpc\Rpc\Transport\FramedConnection |
Low-level framed WebSocket connection |
PhpWebsocketRpc\Rpc\Contract\AuthService |
Built-in auth contract |
PhpWebsocketRpc\Rpc\Auth\User |
Authenticated user value object |
PhpWebsocketRpc\Rpc\Exception\AuthenticationException |
Auth failure (-32010) |
PhpWebsocketRpc\Rpc\Exception\AuthorizationException |
Forbidden (-32011) |