goalgorilla / graphql-php-ws
Ratchet 的 GraphQL WebSocket 中间件。
0.2.0
2023-10-27 13:13 UTC
Requires
- php: >=7.4
- ext-json: *
- bunny/bunny: ^0.4.3 || ^0.5.0
- cboden/ratchet: ^0.4.3
- psr/log: ^1.0 || ^2.0 || ^3.0
- webonyx/graphql-php: ^14.8
This package is auto-updated.
Last update: 2024-08-30 01:17:49 UTC
README
这是一个使用 GraphQL over WebSocket 协议 和 Ratchet 实现的 PHP 库。
正在进行
这个库正在积极开发中,其接口、实现和使用可能会发生变化。如果您不打算投入时间重写基于此库的应用程序,请不要使用它。
用法
<?php use GraphQL\Language\AST\OperationDefinitionNode; use GraphQLWs\GraphQLWsSubscriberInterface; use GraphQLWs\GraphQLWsSubscriptionServer; use Ratchet\Http\HttpServer; use Ratchet\Server\IoServer; use Ratchet\WebSocket\WsConnection; use Ratchet\WebSocket\WsServer; use React\EventLoop\Factory; use React\Socket\Server as Reactor; use Symfony\Component\HttpKernel\Log\Logger; class RedisEventQueue implements GraphQLWsSubscriberInterface { /** * The subscriptions listening to our GraphQL */ protected array $subscriptions = []; /** * Called with new subscribers. * * {@inheritdoc} */ public function onSubscribe(string $subscription_id, WsConnection $client, OperationDefinitionNode $query, ?string $operationName = NULL, ?array $variables = NULL) : void{ $this->subscriptions[$subscription_id] = [ 'client' => $client, 'query' => $query, 'operationName' => $operationName, 'variables' => $variables, ]; } /** * Called when connections are closed. * * {@inheritdoc} */ public function onComplete(string $subscription_id) : void{ unset($this->subscriptions[$subscription_id]); } /** * Example function receiving data from an event system (e.g. a Redis queue). */ public function onData($data) { // For this example we simply naïvely write the data to the client. This is // most certainly a GraphQL error. This is where you'd actually resolve the // queries your subscribers are subscribed to with the new data. This can be // made easier by doing some double bookkeeping in the onSubscribe event // handler but that's out of the scope of this example. foreach ($this->subscriptions as $subscription) { $subscription['client']->send(json_encode($data)); } } } $ws_address = "localhost:8000"; $logger = new Logger(); $event_loop = Factory::create(); // Something that receives new data from an external system and keeps track of // subscriptions. Any new data is sent to the subscriptions that have asked for // the data. $subscription_handler = new RedisEventQueue($event_loop); // Set up the Websocket server. It requires an event loop to handle some // timeouts that are part of the GraphQL WS Protocol. $subscription_server = new GraphQLWsSubscriptionServer($logger, $event_loop); $subscription_server->addEventHandler($subscription_handler); // Set up our actual stack that handles HTTP and WebSockets. The server above is // only the protocol handler itself. $ws_app = new HttpServer(new WsServer($subscription_server)); $ws_socket = new Reactor($ws_address, $this->eventLoop); new IoServer($ws_app, $ws_socket, $this->eventLoop); $logger->info( "Listening for WebSocket connections on ws://{address}", ["address" => $ws_address] ); // Kick-off the React event loop to start our server. $event_loop->run();