|
| 1 | +# Registering Message Handlers |
| 2 | + |
| 3 | +At its core, the websocket server uses [message handlers](/open-source/packages/websocket-server/docs/1.x/message-handler) to handle incoming WAMP messages. Message handlers are the last classes to be called in the websocket server's middleware stack and are directly responsible for processing the incoming request. |
| 4 | + |
| 5 | +## Example Handlers |
| 6 | + |
| 7 | +The below classes are simplified examples of message handlers covering both RPC and Topic (PubSub) handlers. In these examples, we are using the bundle's `AsMessageHandler` attribute to autoconfigure the service and define the route definition for the websocket server's router. |
| 8 | + |
| 9 | +### RPC Message Handler |
| 10 | + |
| 11 | +This example handler will add all the numeric values provided in the parameters and return the result to the connected client. |
| 12 | + |
| 13 | +```php |
| 14 | +<?php declare(strict_types=1); |
| 15 | + |
| 16 | +namespace App\WebSocket\MessageHandler; |
| 17 | + |
| 18 | +use BabDev\WebSocket\Server\RPCMessageHandler; |
| 19 | +use BabDev\WebSocket\Server\WAMP\WAMPConnection; |
| 20 | +use BabDev\WebSocket\Server\WAMP\WAMPMessageRequest; |
| 21 | +use BabDev\WebSocketBundle\Attribute\AsMessageHandler; |
| 22 | + |
| 23 | +#[AsMessageHandler(path: '/arithmetic/add')] |
| 24 | +final class AddValuesMessageHandler implements RPCMessageHandler |
| 25 | +{ |
| 26 | + /** |
| 27 | + * Handles an RPC "CALL" WAMP message from the client. |
| 28 | + * |
| 29 | + * @param string $id The unique ID of the RPC, required to send a "CALLERROR" or "CALLRESULT" message |
| 30 | + */ |
| 31 | + public function onCall(WAMPConnection $connection, string $id, WAMPMessageRequest $request, array $params): void |
| 32 | + { |
| 33 | + $connection->callResult($id, ['sum' => array_sum($params)]); |
| 34 | + } |
| 35 | +} |
| 36 | +``` |
| 37 | + |
| 38 | +### Topic Message Handler |
| 39 | + |
| 40 | +This example handler will simply echo the provided event to all subscribers connected to a topic. |
| 41 | + |
| 42 | +```php |
| 43 | +<?php declare(strict_types=1); |
| 44 | + |
| 45 | +namespace App\WebSocket\MessageHandler; |
| 46 | + |
| 47 | +use BabDev\WebSocket\Server\Connection; |
| 48 | +use BabDev\WebSocket\Server\TopicMessageHandler; |
| 49 | +use BabDev\WebSocket\Server\WAMP\Topic; |
| 50 | +use BabDev\WebSocket\Server\WAMP\WAMPConnection; |
| 51 | +use BabDev\WebSocket\Server\WAMP\WAMPMessageRequest; |
| 52 | +use BabDev\WebSocketBundle\Attribute\AsMessageHandler; |
| 53 | + |
| 54 | +#[AsMessageHandler(path: '/echo')] |
| 55 | +final class EchoMessageHandler implements TopicMessageHandler |
| 56 | +{ |
| 57 | + public function onSubscribe(WAMPConnection $connection, Topic $topic, WAMPMessageRequest $request): void |
| 58 | + { |
| 59 | + $topic->broadcast(['msg' => 'Connection opened'], [], [$connection->getAttributeStore()->get('wamp.session_id')]); |
| 60 | + } |
| 61 | + |
| 62 | + public function onUnsubscribe(WAMPConnection $connection, Topic $topic, WAMPMessageRequest $request): void |
| 63 | + { |
| 64 | + $topic->broadcast(['msg' => 'Connection closed'], [], [$connection->getAttributeStore()->get('wamp.session_id')]); |
| 65 | + } |
| 66 | + |
| 67 | + /** |
| 68 | + * Handles a "PUBLISH" WAMP message from the client. |
| 69 | + * |
| 70 | + * @param array|string $event The event payload for the message |
| 71 | + * @param list<string> $exclude A list of session IDs the message should be excluded from |
| 72 | + * @param list<string> $eligible A list of session IDs the message should be sent to |
| 73 | + */ |
| 74 | + public function onPublish(Connection $connection, Topic $topic, WAMPMessageRequest $request, array|string $event, array $exclude, array $eligible): void |
| 75 | + { |
| 76 | + $topic->broadcast($event, $exclude, $eligible); |
| 77 | + } |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +## Configuring the WebSocket Router |
| 82 | + |
| 83 | +The websocket server uses the [Symfony Routing Component](https://symfony.com/doc/current/routing.html) to manage its routes. This means that with one exception (the attribute class used on message handlers), all configuration for the Symfony router applies to the websocket server as well. |
| 84 | + |
| 85 | +When using attributes to configure routes, the `BabDev\WebSocketBundle\Attribute\AsMessageHandler` class should be used instead of the `Symfony\Component\Routing\Attribute\Route` class. |
| 86 | + |
| 87 | +### Debugging the WebSocket Router |
| 88 | + |
| 89 | +The bundle also provides support for debugging the websocket router with the `babdev:websocket-server:debug:router` command, which provides the same capabilities as the framework's `debug:router` command. |
| 90 | + |
| 91 | +## Registering Message Handler Services |
| 92 | + |
| 93 | +When using the `AsMessageHandler` attribute, the bundle will automatically tag message handler services to use in your application. If not using the attribute, services will need the `babdev_websocket_server.message_handler` service tag instead. |
| 94 | + |
| 95 | +```yaml |
| 96 | +# config/services.yaml |
| 97 | +services: |
| 98 | + App\WebSocket\MessageHandler\EchoMessageHandler: |
| 99 | + tags: |
| 100 | + - { name: babdev_websocket_server.message_handler } |
| 101 | +``` |
0 commit comments