Configuration
Pick the broadcast connection with .env, tune the Reverb driver and understand the X-Socket-ID header the provider adds.
On this page
Basic Usage#
BROADCAST_CONNECTION=reverb
REVERB_HOST=api.example.com
REVERB_PORT=443
REVERB_SCHEME=wss
REVERB_APP_KEY=my-app-key
broadcastingConfig, exported from the package barrel, reads these keys and builds the broadcasting config. Nothing is copied into your app: the installer registers () => broadcastingConfig in configFactories and you change behaviour through .env.
Quick Reference#
| Key | Type | Default | Meaning |
|---|---|---|---|
broadcasting.default |
String |
null |
The connection Echo uses, from BROADCAST_CONNECTION. |
broadcasting.connections.reverb |
Map |
see below | The Reverb (Pusher protocol) websocket driver. |
broadcasting.connections.null |
Map |
{driver: null} |
The no-op driver. |
Connections#
| Connection | Driver | Use |
|---|---|---|
reverb |
ReverbBroadcastDriver |
Laravel Reverb, Soketi or any Pusher-protocol server, over a pure Dart websocket. |
null |
NullBroadcastDriver |
Local development and tests; every operation succeeds and nothing is delivered. |
A connection with an unknown driver name falls back to the null driver. Register your own name with BroadcastManager.extend, see Extending.
Environment Keys#
| Key | Default | Feeds |
|---|---|---|
BROADCAST_CONNECTION |
null |
broadcasting.default |
REVERB_HOST |
localhost |
host |
REVERB_PORT |
8080 |
port; a non-numeric value falls back to 8080 |
REVERB_SCHEME |
ws |
scheme; use wss behind TLS |
REVERB_APP_KEY |
empty | app_key |
Reverb Options#
| Key | Type | Default | Meaning |
|---|---|---|---|
host, port, scheme |
String, int, String |
from .env |
The websocket endpoint. |
app_key |
String |
from .env |
The application key; must match the server. |
auth_endpoint |
String |
/broadcasting/auth |
The HTTP route for private and presence auth. |
reconnect |
bool |
true |
Reconnect after an unexpected disconnect. |
max_reconnect_delay |
int |
30000 |
Cap of the reconnect backoff, in milliseconds. |
activity_timeout |
int |
120 |
Seconds of silence before the driver pings; the server value wins after the handshake. |
connection_timeout |
int |
15 |
Seconds to wait for pusher:connection_established. |
The last five keys are not read from .env. To change one, wrap the factory and override it:
import 'package:magic/magic.dart';
import 'package:magic_socket/magic_socket.dart';
Map<String, dynamic> myBroadcastingConfig() {
final config = broadcastingConfig;
final reverb = (config['broadcasting'] as Map)['connections']['reverb'] as Map;
reverb['max_reconnect_delay'] = 10000;
return config;
}
Future<void> main() async {
await Magic.init(configFactories: [myBroadcastingConfig]);
}
Register myBroadcastingConfig in configFactories instead of () => broadcastingConfig.
The Provider#
BroadcastServiceProvider is not auto-registered.
| Phase | What it does |
|---|---|
register() |
Binds the BroadcastManager singleton at broadcasting. |
boot() |
Skips everything when broadcasting.default is null. Otherwise adds SocketIdInterceptor to the network driver (when one is bound) and starts connecting without waiting. |
Boot does not wait for the socket. A server that is down or slow never holds or fails the app launch: the failure is logged with Log.warning and the driver keeps retrying. Code that needs the socket awaits Echo.connect(), which joins the attempt already in flight.
Excluding the Sender#
Laravel's broadcast($event)->toOthers() skips the socket that made the request, but only when the request carries an X-Socket-ID header. SocketIdInterceptor sets it from Echo.socketId on every outgoing Http request, so the device that made a change does not receive its own event back.
| Situation | Header |
|---|---|
| Socket connected | X-Socket-ID: <id> |
| Socket down | Not sent; the header is never empty. |
null driver |
Not sent; the interceptor is not registered. |
| No network driver bound | The interceptor is skipped; add NetworkServiceProvider to the providers list. |
The Null Driver#
NullBroadcastDriver is the default. connect and disconnect resolve at once, socketId is null, isConnected is false, and channels accept listen and never emit. Code written against Echo therefore compiles and runs with no server. To exercise handlers without one, use Echo.fake.
Gotchas#
| Mistake | Fix |
|---|---|
Putting broadcastingConfig in configs |
It reads .env; register it in configFactories so it runs after .env loads. |
Forgetting REVERB_APP_KEY |
The handshake is refused; the key must equal the server's REVERB_APP_KEY. |
Using ws against a TLS endpoint |
Set REVERB_SCHEME=wss. |
Expecting Echo.socketId right after Magic.init |
Boot does not wait; await Echo.connect() first. |
toOthers() has no effect |
The request had no X-Socket-ID: connection null, socket down, or no NetworkServiceProvider. |
Setting BROADCAST_CONNECTION=pusher with no driver |
An unknown name resolves to the null driver; register it with BroadcastManager.extend. |
Related Documentation#
- Installation: registering the provider and the config factory.
- Channels: subscribing and listening.
- Connection: timeouts, backoff and close codes.
- Extending: interceptors and custom drivers.