0
# Broadcasting Connectors
1
2
WebSocket client abstractions providing consistent APIs across different broadcasting services with automatic authentication and connection management.
3
4
## Capabilities
5
6
### Base Connector Class
7
8
Abstract base class providing common connector functionality for all broadcasting services.
9
10
```typescript { .api }
11
/**
12
* Base connector class for WebSocket broadcasting services
13
*/
14
abstract class Connector<TBroadcastDriver, TPublic, TPrivate, TPresence> {
15
/** Default connector options */
16
static readonly _defaultOptions: {
17
auth: { headers: Record<string, string> };
18
authEndpoint: string;
19
userAuthentication: { endpoint: string; headers: Record<string, string> };
20
csrfToken: string | null;
21
bearerToken: string | null;
22
host: string | null;
23
key: string | null;
24
namespace: string;
25
};
26
27
/** Connector options merged with defaults */
28
options: EchoOptionsWithDefaults<TBroadcastDriver>;
29
30
/** Create a new connector instance and automatically connect */
31
constructor(options: EchoOptions<TBroadcastDriver>);
32
33
/** Create a fresh connection to the WebSocket service */
34
abstract connect(): void;
35
36
/** Disconnect from the WebSocket service */
37
abstract disconnect(): void;
38
39
/** Get a public channel instance by name */
40
abstract channel(channel: string): TPublic;
41
42
/** Get a private channel instance by name */
43
abstract privateChannel(channel: string): TPrivate;
44
45
/** Get a presence channel instance by name */
46
abstract presenceChannel(channel: string): TPresence;
47
48
/** Leave the given channel and its variants */
49
abstract leave(channel: string): void;
50
51
/** Leave the specific channel */
52
abstract leaveChannel(channel: string): void;
53
54
/** Get the socket ID of the current connection */
55
abstract socketId(): string | undefined;
56
57
/** Listen for events on a channel by name */
58
listen(name: string, event: string, callback: CallableFunction): TPublic;
59
60
/** Merge custom options with defaults */
61
protected setOptions(options: EchoOptions<TBroadcastDriver>): void;
62
63
/** Extract CSRF token from the page or options */
64
protected csrfToken(): string | null;
65
}
66
```
67
68
### Pusher Connector
69
70
Connector for Pusher-based broadcasting services (Pusher, Reverb, Ably).
71
72
```typescript { .api }
73
/**
74
* Connector for Pusher-based broadcasting services
75
*/
76
class PusherConnector<T extends BroadcastDriver> extends Connector<
77
T,
78
PusherChannel<T>,
79
PusherPrivateChannel<T>,
80
PusherPresenceChannel<T>
81
> {
82
/** The Pusher client instance */
83
pusher: Pusher;
84
85
/** All subscribed channel instances */
86
channels: Record<string, PusherChannel<T> | PusherPrivateChannel<T> | PusherPresenceChannel<T>>;
87
88
/** Pusher-specific options */
89
declare options: PusherOptions<T>;
90
91
/** Create a fresh Pusher connection */
92
connect(): void;
93
94
/** Get a public channel instance */
95
channel(channel: string): PusherChannel<T>;
96
97
/** Get a private channel instance */
98
privateChannel(channel: string): PusherPrivateChannel<T>;
99
100
/** Get an encrypted private channel instance */
101
encryptedPrivateChannel(channel: string): PusherEncryptedPrivateChannel<T>;
102
103
/** Get a presence channel instance */
104
presenceChannel(channel: string): PusherPresenceChannel<T>;
105
106
/** Leave channel and its variants */
107
leave(channel: string): void;
108
109
/** Leave specific channel */
110
leaveChannel(channel: string): void;
111
112
/** Get current socket ID */
113
socketId(): string | undefined;
114
115
/** Listen for events on a channel by name */
116
listen(name: string, event: string, callback: CallableFunction): PusherChannel<T>;
117
118
/** Disconnect from Pusher */
119
disconnect(): void;
120
}
121
122
/** Pusher-specific configuration options */
123
interface PusherOptions<T extends BroadcastDriver> extends EchoOptionsWithDefaults<T> {
124
key: string;
125
Pusher?: typeof Pusher;
126
cluster?: string;
127
wsHost?: string;
128
wsPort?: number;
129
wssPort?: number;
130
forceTLS?: boolean;
131
enabledTransports?: string[];
132
disabledTransports?: string[];
133
}
134
```
135
136
**Usage Examples:**
137
138
```typescript
139
// The connector is typically used internally by Echo
140
// but can be accessed for advanced use cases
141
142
const echo = new Echo({
143
broadcaster: "pusher",
144
key: "your-pusher-key",
145
cluster: "us2",
146
wsHost: "ws.example.com",
147
wsPort: 443,
148
forceTLS: true,
149
});
150
151
// Access the underlying connector
152
const connector = echo.connector;
153
154
// Get raw Pusher instance for advanced features
155
// @ts-ignore - accessing internal property
156
const pusher = connector.pusher;
157
158
// Listen to connection state changes
159
pusher.connection.bind("state_change", (states) => {
160
console.log("Connection state changed:", states);
161
});
162
```
163
164
### Socket.IO Connector
165
166
Connector for Socket.IO broadcasting service.
167
168
```typescript { .api }
169
/**
170
* Connector for Socket.IO broadcasting service
171
*/
172
class SocketIoConnector extends Connector<
173
"socket.io",
174
SocketIoChannel,
175
SocketIoPrivateChannel,
176
SocketIoPresenceChannel
177
> {
178
/** The Socket.IO client instance */
179
socket: SocketIOClient.Socket;
180
181
/** All subscribed channel instances */
182
channels: Record<string, SocketIoChannel | SocketIoPrivateChannel | SocketIoPresenceChannel>;
183
184
/** Create a fresh Socket.IO connection */
185
connect(): void;
186
187
/** Get a public channel instance */
188
channel(channel: string): SocketIoChannel;
189
190
/** Get a private channel instance */
191
privateChannel(channel: string): SocketIoPrivateChannel;
192
193
/** Get a presence channel instance */
194
presenceChannel(channel: string): SocketIoPresenceChannel;
195
196
/** Leave channel and its variants */
197
leave(channel: string): void;
198
199
/** Leave specific channel */
200
leaveChannel(channel: string): void;
201
202
/** Get current socket ID */
203
socketId(): string | undefined;
204
205
/** Listen for events on a channel by name */
206
listen(name: string, event: string, callback: CallableFunction): SocketIoChannel;
207
208
/** Disconnect from Socket.IO server */
209
disconnect(): void;
210
}
211
```
212
213
**Usage Examples:**
214
215
```typescript
216
const echo = new Echo({
217
broadcaster: "socket.io",
218
host: window.location.hostname + ":6001",
219
namespace: "/chat",
220
});
221
222
// Socket.IO doesn't support encrypted private channels
223
// This will throw an error:
224
// echo.encryptedPrivate("sensitive-data"); // Error!
225
226
// Use regular private channels instead
227
echo.private("user.1").listen("PrivateMessage", (e) => {
228
console.log("Private message:", e.message);
229
});
230
```
231
232
### Null Connector
233
234
Mock connector for testing and development environments.
235
236
```typescript { .api }
237
/**
238
* Null/mock connector for testing purposes
239
*/
240
class NullConnector extends Connector<
241
"null",
242
NullChannel,
243
NullPrivateChannel,
244
NullPresenceChannel
245
> {
246
/** Mock channel storage */
247
channels: Record<string, NullChannel | NullPrivateChannel | NullPresenceChannel>;
248
249
/** Mock connection (no-op) */
250
connect(): void;
251
252
/** Get a mock public channel */
253
channel(channel: string): NullChannel;
254
255
/** Get a mock private channel */
256
privateChannel(channel: string): NullPrivateChannel;
257
258
/** Get a mock encrypted private channel */
259
encryptedPrivateChannel(channel: string): NullEncryptedPrivateChannel;
260
261
/** Get a mock presence channel */
262
presenceChannel(channel: string): NullPresenceChannel;
263
264
/** Mock leave functionality */
265
leave(channel: string): void;
266
267
/** Mock leave channel functionality */
268
leaveChannel(channel: string): void;
269
270
/** Mock socket ID (returns null) */
271
socketId(): string | undefined;
272
273
/** Mock listen functionality (returns new NullChannel) */
274
listen(name: string, event: string, callback: CallableFunction): NullChannel;
275
276
/** Mock disconnect (no-op) */
277
disconnect(): void;
278
}
279
```
280
281
**Usage Examples:**
282
283
```typescript
284
// Useful for testing without real WebSocket connections
285
const echo = new Echo({
286
broadcaster: "null",
287
withoutInterceptors: true,
288
});
289
290
// All methods work but don't actually connect anywhere
291
echo.channel("test")
292
.listen("TestEvent", (e) => {
293
// This callback will never be called in null mode
294
console.log("Test event:", e);
295
});
296
297
// Null connector supports all channel types including encrypted
298
echo.encryptedPrivate("test").listen("Encrypted", (e) => {
299
// Mock functionality - no actual encryption
300
});
301
```
302
303
## Connector Configuration
304
305
### Default Options
306
307
All connectors inherit these default options:
308
309
```typescript { .api }
310
interface DefaultConnectorOptions {
311
auth: {
312
headers: Record<string, string>;
313
};
314
authEndpoint: string; // "/broadcasting/auth"
315
userAuthentication: {
316
endpoint: string; // "/broadcasting/user-auth"
317
headers: Record<string, string>;
318
};
319
csrfToken: string | null;
320
bearerToken: string | null;
321
host: string | null;
322
key: string | null;
323
namespace: string; // "App.Events"
324
}
325
```
326
327
### Authentication Configuration
328
329
Connectors automatically handle authentication for private and presence channels:
330
331
```typescript
332
const echo = new Echo({
333
broadcaster: "pusher",
334
key: "your-key",
335
336
// Custom auth endpoint
337
authEndpoint: "/api/broadcasting/auth",
338
339
// Additional auth headers
340
auth: {
341
headers: {
342
"X-API-Key": "your-api-key",
343
},
344
},
345
346
// Bearer token authentication
347
bearerToken: "your-jwt-token",
348
349
// Custom user authentication for presence channels
350
userAuthentication: {
351
endpoint: "/api/broadcasting/user-auth",
352
headers: {
353
"X-Custom-Header": "value",
354
},
355
},
356
});
357
```
358
359
### CSRF Token Handling
360
361
Connectors automatically extract CSRF tokens from multiple sources:
362
363
```typescript
364
// From Laravel meta tag
365
<meta name="csrf-token" content="your-csrf-token">
366
367
// From window.Laravel object
368
window.Laravel = {
369
csrfToken: "your-csrf-token"
370
};
371
372
// Or explicitly in options
373
const echo = new Echo({
374
broadcaster: "pusher",
375
key: "your-key",
376
csrfToken: "your-csrf-token",
377
});
378
```
379
380
## Error Handling
381
382
Connectors provide error handling capabilities:
383
384
```typescript
385
// Connection errors
386
echo.connector.connect();
387
388
// Channel subscription errors
389
echo.channel("orders")
390
.error((error) => {
391
console.error("Channel subscription failed:", error);
392
});
393
394
// Listen for connection state changes (Pusher)
395
if (echo.connector instanceof PusherConnector) {
396
echo.connector.pusher.connection.bind("error", (error) => {
397
console.error("Connection error:", error);
398
});
399
}
400
```