Skip to content

Commit b837940

Browse files
committed
Merge branch '0.1' of github.com:BabDev/WebSocketBundle into 0.1
2 parents 4c8a571 + a9b8150 commit b837940

File tree

8 files changed

+188
-35
lines changed

8 files changed

+188
-35
lines changed

docs/authentication.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,24 @@ To enable the session authenticator, you must add it to the `providers` list in
1919

2020
```yaml
2121
services:
22-
session.handler.pdo:
23-
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
24-
arguments:
25-
- !service { class: PDO, factory: ['@database_connection', 'getWrappedConnection'] }
26-
- { lock_mode: 0 }
22+
session.handler.pdo:
23+
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
24+
arguments:
25+
- !service { class: PDO, factory: ['@database_connection', 'getWrappedConnection'] }
26+
- { lock_mode: 0 }
2727

2828
framework:
29-
session:
30-
handler_id: 'session.handler.pdo'
29+
session:
30+
handler_id: 'session.handler.pdo'
3131

3232
babdev_websocket:
33-
authentication:
34-
providers:
35-
session:
36-
firewalls: ~
37-
server:
38-
session:
39-
handler_service_id: 'session.handler.pdo'
33+
authentication:
34+
providers:
35+
session:
36+
firewalls: ~
37+
server:
38+
session:
39+
handler_service_id: 'session.handler.pdo'
4040
```
4141
4242
Configuring the session handler will add the [`InitializeSession` middleware](/open-source/packages/websocket-server/docs/1.x/middleware/initialize-session) to the websocket server which will provide a read-only interface for the session data from your website.
@@ -45,10 +45,10 @@ By default, the session authentication provider will attempt to authenticate to
4545

4646
```yaml
4747
babdev_websocket:
48-
authentication:
49-
providers:
50-
session:
51-
firewalls: ['main'] # This can be an array to specify multiple firewalls or a string when specifying a single firewall
48+
authentication:
49+
providers:
50+
session:
51+
firewalls: ['main'] # This can be an array to specify multiple firewalls or a string when specifying a single firewall
5252
```
5353

5454
### Registering New Authenticators

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
- [Events](/open-source/packages/websocketbundle/docs/1.x/events)
66
- [Managing Middleware](/open-source/packages/websocketbundle/docs/1.x/managing-middleware)
77
- [Periodic Manager](/open-source/packages/websocketbundle/docs/1.x/periodic-manager)
8+
- [Registering Message Handlers](/open-source/packages/websocketbundle/docs/1.x/registering-message-handlers)
89
- [Securing Connections](/open-source/packages/websocketbundle/docs/1.x/securing-connections)

docs/installation.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,52 @@ return [
1919
BabDev\WebSocketBundle\BabDevWebSocketBundle::class => ['all' => true],
2020
];
2121
```
22+
23+
## Configure The Bundle
24+
25+
Because a Flex recipe is not published for the bundle at this time, you will need to manually configure the bundle to fully enable its features. The below example can be written to `config/packages/babdev_websocket.yaml` in your application as a starting point:
26+
27+
```yaml
28+
babdev_websocket:
29+
authentication:
30+
providers:
31+
session:
32+
firewalls: ~
33+
server:
34+
uri: '%env(BABDEV_WEBSOCKET_SERVER_URI)%'
35+
router:
36+
resource: '%kernel.project_dir%/config/websocket_router.yaml'
37+
session:
38+
handler_service_id: 'session.handler.pdo'
39+
```
40+
41+
In this example, we:
42+
43+
- Enable the [session authentication provider](/open-source/packages/websocketbundle/docs/1.x/authentication) and allow sessions for all firewalls
44+
- Configure the address the server will listen to connections on using the `BABDEV_WEBSOCKET_SERVER_URI` environment variable
45+
- Configure the router resource for the websocket server
46+
- Configure the session handler that is used to read session data for incoming connections (for our example, we are using a PDO session handler but this can be any shared resource such as the database or Redis)
47+
48+
### Configuring the WebSocket Server Address
49+
50+
The `babdev_websocket.server.uri` configuration node is used to define what address and port the websocket server process will listen for incoming connections on. The below snippet can be added to your application's `.env` file to define a sane default for local development, which will listen for connections on localhost at port 8080:
51+
52+
```properties
53+
###> babdev/websocket-bundle ###
54+
BABDEV_WEBSOCKET_SERVER_URI=127.0.0.1:8080
55+
###< babdev/websocket-bundle ###
56+
```
57+
58+
### Configuring the WebSocket Server Router
59+
60+
The websocket server uses the Symfony Routing component to power its routing implementation, which requires a second router service to be configured in your application. Most of this is taken care of already in the bundle, however, you will need to add a file in your application to define the routes for the websocket server. The below example, which is based on the default `config/routes.yaml` added to applications, can be saved to your application at `config/websocket_router.yaml`:
61+
62+
```yaml
63+
controllers:
64+
resource:
65+
path: ../src/WebSocket/
66+
namespace: App\WebSocket
67+
type: attribute
68+
```
69+
70+
Similar to the default router configuration, this will scan for the `AsMessageHandler` attribute on classes in your `src/WebSocket` directory.

docs/managing-middleware.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ If you are not using autoconfiguration, the service should be tagged with the `b
4848
```yaml
4949
# config/services.yaml
5050
services:
51-
App\WebSocket\Middleware\EarlyMiddleware:
52-
arguments:
53-
- !abstract decorated middleware
54-
tags:
55-
- { name: babdev_websocket_server.server_middleware, priority: -75 }
51+
App\WebSocket\Middleware\EarlyMiddleware:
52+
arguments:
53+
- !abstract decorated middleware
54+
tags:
55+
- { name: babdev_websocket_server.server_middleware, priority: -75 }
5656
```

docs/periodic-manager.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ The `BabDev\WebSocketBundle\PeriodicManager\PeriodicManager` interface represent
44

55
Periodic managers are initialized during the `BabDev\WebSocketBundle\Event\BeforeRunServer` event and the manager is responsible for registering its actions to the event loop.
66

7+
The bundle will autoconfigure periodic managers with the `babdev_websocket_server.periodic_manager` service tag, which is required to ensure managers are correctly registered.
8+
79
## Required Methods
810

911
### `getName()`
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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+
```

docs/securing-connections.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ The bundle can be configured to only allow requests when traffic originates from
1111
```yaml
1212
# config/packages/babdev_websocket.yaml
1313
babdev_websocket:
14-
server:
15-
# A list of origins allowed to connect to the websocket server, must match the value from the "Origin" header of the HTTP request.
16-
allowed_origins:
17-
- www.example.com
18-
- example.com
14+
server:
15+
# A list of origins allowed to connect to the websocket server, must match the value from the "Origin" header of the HTTP request.
16+
allowed_origins:
17+
- www.example.com
18+
- example.com
1919
```
2020
2121
With this configuration, only connections from `www.example.com` and `example.com` will be accepted, others will be rejected.
@@ -27,11 +27,11 @@ The bundle can be configured to block traffic from specified IP addresses. The c
2727
```yaml
2828
# config/packages/babdev_websocket.yaml
2929
babdev_websocket:
30-
server:
31-
# A list of IP addresses which are not allowed to connect to the websocket server, each entry can be either a single address or a CIDR range.
32-
blocked_ip_addresses:
33-
- 8.8.8.8
34-
- 192.168.1.0/24
30+
server:
31+
# A list of IP addresses which are not allowed to connect to the websocket server, each entry can be either a single address or a CIDR range.
32+
blocked_ip_addresses:
33+
- 8.8.8.8
34+
- 192.168.1.0/24
3535
```
3636

3737
With this configuration, all connections from `8.8.8.8` and the `192.168.1.0/24` range will be rejected.

src/Attribute/AsMessageHandler.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
* 1) Register the message handler as a service within the container
1313
* 2) Configure the route definition for the message handler to be used with the websocket server's router
1414
*
15-
* Because of the second purpose, this attribute purposefully inherits from the {@see Route} annotation/attribute class
16-
* from Symfony's Routing component to allow using its annotation/attribute loaders.
15+
* Because of the second purpose, this attribute purposefully inherits from the {@see Route} attribute class
16+
* from Symfony's Routing component to allow using its attribute loaders.
1717
*/
1818
#[\Attribute(\Attribute::TARGET_CLASS)]
1919
final class AsMessageHandler extends Route {}

0 commit comments

Comments
 (0)