uzdevid / yii-centrifugo
Centrifugo & RoadRunner based Yii runner
Fund package maintenance!
Open Collective
yiisoft
Requires
- php: ^8.1
- psr/container: ^2.0
- roadrunner-php/centrifugo: ^2.2
- spiral/roadrunner: ^2024.1
- yiisoft/definitions: ^1.0|^2.0|^3.0
- yiisoft/di: ^1.0
- yiisoft/error-handler: ^3.0
- yiisoft/log: ^2.0
- yiisoft/log-target-file: ^3.0
- yiisoft/yii-runner: ^2.0
Requires (Dev)
- maglnet/composer-require-checker: ^4.7
- phpunit/phpunit: ^10.5
- rector/rector: ^1.2
- roave/infection-static-analysis-plugin: ^1.34
- spatie/phpunit-watcher: ^1.23
- vimeo/psalm: ^5.20
- yiisoft/config: ^1.1
- yiisoft/test-support: ^3.0
This package is auto-updated.
Last update: 2025-04-18 18:10:57 UTC
README
Yii RoadRunner Centrifugo
The package is designed to process web sockets on the basis of Centrifugo and Roadrunner
Requirements
- PHP 8.1 or higher.
Installation
The package could be installed with Composer:
composer require uzdevid/yii-runner-centrifugo
General usage
Centrifugo
Download binary file
Generate Centrifugo config file: config.json
./centrifugo genconfig
Example config
{ "log": { "level": "debug" }, "client": { "token": { "hmac_secret_key": "<secret>" }, "allowed_origins": [ "*" ], "proxy": { "connect": { "enabled": true, "endpoint": "grpc://127.0.0.1:30000", "timeout": "10s" }, "refresh": { "enabled": true, "endpoint": "grpc://127.0.0.1:30000", "timeout": "3s" } } }, "channel": { "namespaces": [ { "name": "<channel>", "allow_subscribe_for_client": true, "allow_publish_for_client": true, "subscribe_proxy_enabled": true, "publish_proxy_enabled": true } ], "proxy": { "subscribe": { "endpoint": "grpc://127.0.0.1:30000", "timeout": "3s" }, "publish": { "endpoint": "grpc://127.0.0.1:30000", "timeout": "3s" }, "sub_refresh": { "endpoint": "grpc://127.0.0.1:30000", "timeout": "3s" } } }, "admin": { "enabled": true, "password": "<password>", "secret": "<secret>" }, "grpc_api": { "address": "127.0.0.1", "port": 30000 } }
We set up the proxy for all requests for our Roadrunner server at
grpc://127.0.0.1:30000
, according to the gRPC protocol
See also: https://centrifugal.dev/docs/server/proxy
RoadRunner
Download roadrunner binary file
Road runner example config: .rr.yaml
version: '3' rpc: listen: tcp://127.0.0.1:6001 server: command: "php ./worker.php" relay: pipes centrifuge: proxy_address: tcp://127.0.0.1:30000 grpc_api_address: tcp://127.0.0.1:30000 use_compressor: true service: centrifuge: service_name_in_log: true remain_after_exit: true restart_sec: 1 command: "./centrifugo"
We listen to the proxies in the address
tcp://127.0.0.1:30000
from the Centrifugo server
Runner file
Create /worker.php
file
use RoadRunner\Centrifugo\Request\RequestFactory; use Spiral\RoadRunner\Worker; use UzDevid\Yii\Runner\Centrifugo\CentrifugoApplicationRunner; use Yiisoft\ErrorHandler\ErrorHandler; use Yiisoft\ErrorHandler\Renderer\PlainTextRenderer; use Yiisoft\Log\Logger; use Yiisoft\Log\Target\File\FileTarget; ini_set('display_errors', 'stderr'); require_once dirname(__DIR__) . '/vendor/autoload.php'; $logger = new Logger([new FileTarget(sprintf('%s/runtime/logs/centrifugo.log', __DIR__))]); $errorHandler = new ErrorHandler($logger, new PlainTextRenderer()); $worker = Worker::create(logger: $logger); $application = new CentrifugoApplicationRunner( rootPath: __DIR__, temporaryErrorHandler: $errorHandler, worker: $worker, requestFactory: new RequestFactory($worker), debug: true ); $application->run();
Handlers
Handling connect request and response with specific payload
use UzDevid\Yii\Runner\Centrifugo\Handler\ConnectHandlerInterface; use RoadRunner\Centrifugo\Payload\ConnectResponse; class ConnectHandler implements ConnectHandlerInterface { public function handle(RequestInterface $request): void { // ... $request->respond(new ConnectResponse('user-id', null, ['ok' => true])) } }
In the same way, implement the rest of the handlers:
ConnectHandlerInterface
- called when a client connects to Centrifugo, so it's possible to authenticate user, return custom initial data to a client, subscribe connection to server-side channels, attach meta information to the connection, and so on. This proxy hook available for both bidirectional and unidirectional transports.RefreshHandlerInterface
- called when a client session is going to expire, so it's possible to prolong it or just let it expire. Can also be used as a periodical connection liveness callback from Centrifugo to the app backend. Works for bidirectional and unidirectional transports.SubscribeHandlerInterface
- called when clients try to subscribe on a channel, so it's possible to check permissions and return custom initial subscription data. Works for bidirectional transports only.PublishHandlerInterface
- called when a client tries to publish into a channel, so it's possible to check permissions and optionally modify publication data. Works for bidirectional transports only.SubRefreshHandlerInterface
- called when a client subscription is going to expire, so it's possible to prolong it or just let it expire. Can also be used just as a periodical subscription liveness callback from Centrifugo to app backend. Works for bidirectional and unidirectional transports.InvalidRequestInterface
- Handle invalid requestRpcHandlerInterface
- called when a client sends RPC, you can do whatever logic you need based on a client-provided RPC method and data. Works for bidirectional transports only (and bidirectional emulation), since data is sent from client to the server in this case.
Run RoadRunner
./rr serve
You can test the WebSocketing service or use the Client SDK
Documentation
If you need help or have a question, the Yii Forum is a good place for that. You may also check out other Yii Community Resources.
Maintained by UzDevid.