Laravel Echo / Reverb
Socket Conveyor can act as a Pusher/Reverb-compatible WebSocket and REST broadcast server. Laravel keeps using its built-in broadcasting tools.
Start Conveyor in Pusher mode
1<?php
2
3use Conveyor\Constants;
4use Conveyor\ConveyorServer;
5
6require __DIR__ . '/vendor/autoload.php';
7
8(new ConveyorServer())
9 ->host('127.0.0.1')
10 ->port(8990)
11 ->serverOptions([
12 'worker_num' => 1,
13 'task_worker_num' => 1,
14 ])
15 ->conveyorOptions([
16 Constants::WEBSOCKET_SUBPROTOCOL => Constants::PUSHER,
17 Constants::USE_PRESENCE => true,
18 Constants::APPS => [[
19 'app_id' => 'local-app',
20 'key' => 'local-key',
21 'secret' => 'local-secret',
22 'enable_client_messages' => true,
23 'enabled' => true,
24 ]],
25 ])
26 ->start();The repository includes the same setup for local smoke testing:
1php examples/pusher-real/run-conveyor.phpConfigure Laravel
Use Laravel's built-in Reverb-style environment variables and point them at Conveyor:
1BROADCAST_CONNECTION=reverb
2
3REVERB_APP_ID=local-app
4REVERB_APP_KEY=local-key
5REVERB_APP_SECRET=local-secret
6REVERB_HOST=127.0.0.1
7REVERB_PORT=8990
8REVERB_SCHEME=http
9
10VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
11VITE_REVERB_HOST="${REVERB_HOST}"
12VITE_REVERB_PORT="${REVERB_PORT}"
13VITE_REVERB_SCHEME="${REVERB_SCHEME}"If your app uses Laravel's pusher connection instead of reverb, use equivalent PUSHER_* values with the same app id, key, secret, host, port, and scheme.
Laravel applications created with recent versions do not enable broadcasting by default. Install it with the official Artisan command:
1php artisan install:broadcastingThe command will prompt you for the broadcasting service to use. You can also target Reverb directly:
1php artisan install:broadcasting --reverbinstall:broadcasting creates (or ensures) the following:
config/broadcasting.phproutes/channels.php(for your channel authorization callbacks)- The necessary environment variables and bootstrap wiring
If you are on an older Laravel version or have a custom setup, you may need to publish the broadcasting routes and config manually.
Confirm that Laravel registered the authorization route:
1php artisan route:list --name=broadcastingYou should see an entry for broadcasting.auth.
Configure Echo
Install the stock clients:
1npm install laravel-echo pusher-js1import Echo from 'laravel-echo'
2import Pusher from 'pusher-js'
3
4window.Pusher = Pusher
5
6window.Echo = new Echo({
7 broadcaster: 'reverb',
8 key: import.meta.env.VITE_REVERB_APP_KEY,
9 wsHost: import.meta.env.VITE_REVERB_HOST,
10 wsPort: import.meta.env.VITE_REVERB_PORT,
11 wssPort: import.meta.env.VITE_REVERB_PORT,
12 forceTLS: import.meta.env.VITE_REVERB_SCHEME === 'https',
13 enabledTransports: ['ws', 'wss'],
14})For private and presence channels, keep the WebSocket host pointed at Conveyor, but point Echo authorization at your Laravel HTTP app:
1VITE_LARAVEL_URL=http://localhost:80001window.Echo = new Echo({
2 broadcaster: 'reverb',
3 key: import.meta.env.VITE_REVERB_APP_KEY,
4 wsHost: import.meta.env.VITE_REVERB_HOST,
5 wsPort: import.meta.env.VITE_REVERB_PORT,
6 wssPort: import.meta.env.VITE_REVERB_PORT,
7 forceTLS: import.meta.env.VITE_REVERB_SCHEME === 'https',
8 enabledTransports: ['ws', 'wss'],
9 authEndpoint: `${import.meta.env.VITE_LARAVEL_URL}/broadcasting/auth`,
10 auth: {
11 withCredentials: true,
12 },
13})Use Echo normally
1window.Echo.channel('orders')
2 .listen('.OrderShipped', event => {
3 console.log(event)
4 })
5
6window.Echo.private('orders.1')
7 .listen('.OrderUpdated', event => {
8 console.log(event)
9 })
10
11window.Echo.join('room.1')
12 .here(users => console.log('here', users))
13 // ...For the full presence API (.here(), .joining(), .leaving(), .listenForWhisper(), and whispers), see the dedicated Presence page.
Laravel keeps channel authorization in routes/channels.php:
1use Illuminate\Support\Facades\Broadcast;
2
3Broadcast::channel('orders.{orderId}', function ($user, int $orderId) {
4 return true;
5});
6
7Broadcast::channel('room.{roomId}', function ($user, int $roomId) {
8 return [
9 'id' => $user->id,
10 'name' => $user->name,
11 ];
12});Broadcast events normally:
1broadcast(new OrderShipped($order))->toOthers();Conveyor receives Laravel's signed Pusher/Reverb REST publish request at /apps/{app_id}/events, delivers the event to connected Echo clients, and honors socket_id exclusion for toOthers().
Verify with the browser smoke
Terminal 1:
1php examples/pusher-real/run-conveyor.phpTerminal 2:
1php -S 127.0.0.1:8991 examples/pusher-real/router.phpOpen:
1http://127.0.0.1:8991/echo.htmlExpected results:
- The page reaches
connectedand shows asocket_id. - Public, private, and presence subscriptions succeed.
- The Public, Private, and Presence buttons log
DemoEvent. Public toOthers()does not echo to the current tab.- A second tab can receive a whisper from the first tab.
About conveyor-laravel-broadcaster
For Pusher/Reverb-compatible Laravel Echo usage, you should not need the older custom Conveyor Laravel broadcaster. Use Laravel's built-in reverb or pusher driver and point it at Conveyor.
The custom broadcaster package is only relevant for applications that intentionally use Conveyor's native protocol instead of Laravel's Pusher/Reverb protocol.

