You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+41Lines changed: 41 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,6 +33,8 @@ Accepting client connections is performed by an instance of `WebsocketAcceptor`.
33
33
-`Rfc6455Acceptor`: Accepts client connections based on [RFC6455](https://datatracker.ietf.org/doc/html/rfc6455) with no further restrictions.
34
34
-`AllowOriginAcceptor`: Requires the `"Origin"` header of the HTTP request to match one of the allowed origins provided to the constructor. Accepting the connection is then delegated to another `WebsocketAcceptor` implementation (`Rfc6455Acceptor` by default).
35
35
36
+
Both `Rfc6455Acceptor` and `AllowOriginAcceptor` accept an optional `ErrorHandler` as a constructor argument, allowing you to customise the HTTP response returned when a connection is rejected (e.g. to return a JSON error body).
37
+
36
38
### Handling Client Connections
37
39
38
40
Once established, a WebSocket connection is handled by an implementation of `WebsocketClientHandler`. Your application logic will be within an implementation of this interface.
@@ -51,14 +53,53 @@ After accepting a client connection, `WebsocketClientHandler::handleClient()` is
51
53
52
54
This method should not return until the client connection should be closed. Exceptions should not be thrown from this method. Any exception thrown will close the connection with an `UNEXPECTED_SERVER_ERROR` error code (1011) and forward the exception to the HTTP server logger. There is one exception to this: `WebsocketClosedException`, which is thrown when receiving or sending a message to a connection fails due to the connection being closed. If `WebsocketClosedException` is thrown from `handleClient()`, the exception is ignored.
53
55
56
+
### Receiving Messages
57
+
58
+
Messages are received by iterating over the `WebsocketClient` instance or by calling `receive()` directly. The iterator (and `receive()`) returns `null` and exits cleanly when the connection is closed — no try/catch is needed for the normal close case.
59
+
60
+
```php
61
+
// Iterate over incoming messages until the connection closes
62
+
foreach ($client as $message) {
63
+
$payload = $message->buffer();
64
+
$isBinary = $message->isBinary();
65
+
$client->sendText('Echo: ' . $payload);
66
+
}
67
+
```
68
+
69
+
`WebsocketClosedException` is only thrown when the connection is closed while a send or receive operation is already in progress mid-message. It bubbles up through `handleClient()` and is silently swallowed by the `Websocket` handler.
70
+
54
71
### Gateways
55
72
56
73
A `WebsocketGateway` provides a means of collecting WebSocket clients into related groups to allow broadcasting a single message efficiently (and asynchronously) to multiple clients. `WebsocketClientGateway` provided by this library may be used by one or more client handlers to group clients from one or more endpoints (or multiple may be used on a single endpoint if desired). See the [example server](#example-server) below for basic usage of a gateway in a client handler. Clients added to the gateway are automatically removed when the client connection is closed.
57
74
75
+
The `WebsocketGateway` interface provides the following methods:
76
+
77
+
-`broadcastText(string $data, array $excludedClientIds = [])` — send a UTF-8 text message to all connected clients, with an optional exclusion list.
78
+
-`broadcastBinary(string $data, array $excludedClientIds = [])` — same as above for binary messages.
79
+
-`multicastText(string $data, array $clientIds)` / `multicastBinary(...)` — send to a specific set of client IDs.
80
+
-`sendText(string $data, int $clientId)` / `sendBinary(...)` — send to a single client via the gateway's send queue, guaranteeing ordering with any concurrent broadcast or multicast messages.
81
+
-`getClients()` — returns an array of all currently connected `WebsocketClient` instances indexed by client ID.
82
+
83
+
> **Ordering note:** Messages sent with `WebsocketClient::sendText()` / `sendBinary()` directly bypass the gateway's send queue. If you mix direct sends with gateway sends, message order is not guaranteed. Use the gateway's `sendText()`/`sendBinary()` methods when ordering relative to broadcasts matters.
84
+
58
85
### Compression
59
86
60
87
Message compression may optionally be enabled on individual WebSocket endpoints by passing an instance of `WebsocketCompressionContextFactory` to the `Websocket` constructor. Currently, the only implementation available is `Rfc7692CompressionFactory` which implements compression based on [RFC-7692](https://datatracker.ietf.org/doc/html/rfc7692).
61
88
89
+
### Customising the Client Factory
90
+
91
+
By default, `Websocket` creates clients using `Rfc6455ClientFactory`. You can pass your own `Rfc6455ClientFactory` instance (or a custom `WebsocketClientFactory` implementation) to control low-level client behaviour:
92
+
93
+
`Rfc6455ClientFactory` constructor parameters:
94
+
95
+
| Parameter | Default | Description |
96
+
|---|---|---|
97
+
|`$heartbeatQueue`|`PeriodicHeartbeatQueue`| Sends periodic pings to detect dead connections. Pass `null` to disable. |
98
+
|`$rateLimit`|`ConstantRateLimit`| Limits the rate of incoming messages per client. Pass `null` to disable. |
99
+
|`$parserFactory`|`Rfc6455ParserFactory`| Factory for the low-level frame parser. |
100
+
|`$frameSplitThreshold`|`Rfc6455Client::DEFAULT_FRAME_SPLIT_THRESHOLD`| Large messages are split into frames of at most this many bytes. |
101
+
|`$closePeriod`|`Rfc6455Client::DEFAULT_CLOSE_PERIOD`| Seconds to wait for a close frame from the client before forcefully closing the socket. |
102
+
62
103
### Example Server
63
104
64
105
The server below creates a simple WebSocket endpoint which broadcasts all received messages to all other connected clients. [`amphp/http-server-router`](https://github.com/amphp/http-server-router) and [`amphp/http-server-static-content`](https://github.com/amphp/http-server-static-content) are used to attach the `Websocket` handler to a specific route and to serve static files from the `/public` directory if the route is not defined in the router.
0 commit comments