This article covers getting set up with broadcasting real-time events in Laravel from scratch. Once we're done, you'll be able to broadcast events from anywhere in your Laravel application and pick up the data from the client side.
If you prefer to watch, we have a free course covering everything here (and more).
For this article, I'll create a project with the Breeze starter kit (available via laravel new
) and demonstrate using Laravel Echo with Alpine.js. However, every step will work regardless of how you've set up your project.
Let's get started!
If you're new to Laravel, the common terminology we'll use in this article is as follows:
Hopefully that's cleared things up. Let's get broadcasting installed.
By default, Laravel doesn't include broadcasting functionality. To install this, run the following command:
php artisan install:broadcasting
Once this command runs, it'll create the broadcasting.php
config file and a routes/channels.php
file.
You'll also be prompted to install Laravel Reverb. Choose yes.
INFO Published 'broadcasting' configuration file.
INFO Published 'channels' route file.
┌ Would you like to install Laravel Reverb? ───────────────────┐
│ ● Yes / ○ No │
└──────────────────────────────────────────────────────────────┘
You'll also be prompted to install the Node dependancies. Again, choose yes.
INFO Reverb installed successfully.
┌ Would you like to install and build the Node dependencies required for broadcasting? ┐
│ ● Yes / ○ No │
└──────────────────────────────────────────────────────────────────────────────────────┘
Broadcasting is now installed, along with Laravel Reverb and Echo.
On a local machine, we don't need to configure Reverb, but take a look at your .env
file anyway.
The first change is that BROADCAST_CONNECTION
has been changed to reverb
.
BROADCAST_CONNECTION=reverb
This instructs any events you broadcast to be sent to the Reverb connection. These settings are also defined in your .env
file.
REVERB_APP_ID=955910
REVERB_APP_KEY=cpcjylkqykmpqjnhuj4s
REVERB_APP_SECRET=stixgunvgag7naamrv0x
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
On a local development environment, it's highly unlikely you'll need to change anything here.
Note the VITE_
prefixed env keys. These expose the Reverb server information to Vite so js/echo.js
can read them. Open up this file and take a look.
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
})
As we learned earlier, Laravel Echo is the JavaScript package that allows us to connect to our Reverb server so we're able to listen for events. We'll use this later on.
Open up a terminal tab, it's time to run Reverb! You'll need to leave this running.
php artisan reverb:start
You'll see something like this.
INFO Starting server on 0.0.0.0:8080 (localhost).
If you need to debug anything, you can also start Reverb with the --debug
option. This logs out any connection events and any data being sent to the Reverb server. This is fine for local development, but running this in production isn't advised due to the amount of data that'll be logged out.
php artisan reverb:start --debug
Ok, our Reverb server is running. Now, it's (almost) time to broadcast an event.
We'll start by defining the most basic channel type, a public channel. Anyone can connect to this, and there are no authorization rules around it. If you'd like to learn more about private and presence channels, we have a course covering those in detail.
Open up routes/channels.php
and define a new channel like this:
Broadcast::channel('chat', function () {
//
});
(You'll also notice a App.Models.User.{id}
channel defined in here. That's a private channel).
To be honest, that's it! You've just created a channel that we can now broadcast to.
Events in Laravel don't specifically relate to real-time broadcasting, but they can be used to do this too.
If you're new to events in Laravel, these are classes that we can dispatch anywhere in our application and listen to. For example, when a user registers, we might dispatch a UserRegistered
event and have a listener defined to send them an email.
Let's focus on real-time, though. Create your event like this:
php artisan make:event Example
Open up the Example
event. Here's roughly what it'll look like:
class Example
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*/
public function __construct()
{
//
}
public function broadcastOn(): array
{
return [
new PrivateChannel('channel-name'),
];
}
}
The broadcastOn
method returns the channels we want to broadcast to. Luckily for us, we've already defined a channel, so update it to use a standard public Channel
while updating the name:
public function broadcastOn(): array
{
return [
new Channel('chat'),
];
}
Next, and really importantly, we need to instruct this event to be broadcastable by implementing the ShouldBroadcastNow
interface. Add this to the event:
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
class Example implements ShouldBroadcastNow
{
//...
}
You'll need to import the namespace at the top, since it's not available by default in the generated event.
You may have noticed a ShouldBroadcast
interface namespace in the event. If you implement this interface, your event will be queued before being broadcast. Right now, we're just focused on directly broadcasting to our Reverb server without queueing, so that's why we're using ShouldBroadcastNow
.
Where you broadcast events is totally up to you, and depends on what you're building. For the purpose of this article, let's create a web route.
Route::get('/broadcast', function () {
broadcast(new Example());
});
We use the broadcast
function, passing in the Example
event to broadcast this.
Feel free to head over to /broadcast
in your browser. Nothing will happen yet, and if you don't see an error, you know you're on track, and your event is successfully being broadcast to your Reverb server!
If you see a cURL error here, check your Reverb server is running.
We're successfully broadcasting an event to our WebSocket server, but we need to listen in and pick up the event now. Let's connect to our channel.
Once again, I'm using the Breeze starter kit, which gives us access to Alpine.js. We'll use this to work with Echo, but you're welcome to do this with Livewire, Inertia or any other solution you're using.
Register an account with your application, open up dashboard.blade.php
and add the following code anywhere on the page:
<div
x-init="
Echo.channel('chat')
"
>
</div>
Because Laravel Echo is bound to the window
object, we're able to access it anywhere.
Reload the page and check your console for any errors. You can also check the network tab in your developer tools, filter by WS
(WebSocket) and check you have a 101
status code. If so, this means you're now connected to your Reverb server!
If you're not seeing anything, also make sure you're running npm run dev
to compile assets.
Now, we can listen to the Example
event we're broadcasting from the backend. Update Echo to listen to the event like this:
<div
x-init="
Echo.channel('chat')
.listen('Example', (event) => {
console.log(event)
})
"
>
Here, we're using the listen
method to listen to the class name we gave our event. The callback takes the event data and, in this case, dumps it to the console.
Keeping the dashboard opem, head over to the /broadcast
URL in your browser, then return to the dashboard.
You should see an empty array dumped to your console.
[]
Hopefully, your event will roll in, but it's a little empty now. Let's add some data to our event. After all, there's not much point in sending event data to connected clients if there's no data to do anything with.
Open up your Example
event class again, and set an example public property.
class Example implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message = 'Hello';
//...
}
Any public properties you set in your broadcastable events will be sent to your server and thus delivered to all clients.
Head back to /broadcast
in your browser and recheck your console for the new event. You should now see an object with the message
we just added:
{message: 'Hello'}
Any data you now add to your event will be available to the client. For example, you could pass in an entire model:
Route::get('/broadcast', function () {
broadcast(new Example(User::find(1)));
});
And in your event:
class Example implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(public User $user)
{
//
}
//...
}
Now, when you broadcast this, you'll see the JSON-encoded data from the user:
{
"user": {
"id": 1,
"name": "Alex",
"email": "alex@codecourse.com",
"email_verified_at": null,
"created_at": "2024-07-03T20:50:10.000000Z",
"updated_at": "2024-07-03T20:50:10.000000Z"
}
}
One of the most important parts of broadcasting data is not including too much. Firstly, because you're revealing a lot about your model data, and secondly, you may send more data than you need.
To customize what data gets sent with your events, use the broadcastWith
method on your event.
class Example implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(protected User $user)
{
//
}
public function broadcastWith(): array
{
return [
'user' => [
'id' => $this->user->id,
]
];
}
Here, I've changed the User
we're passing in to protected (since it doesn't need to be a public property anymore), and we're now only revealing the user ID. This is just an example, so customize broadcastWith
to output the data you need.
Nice, you're now broadcasting real-time events in Laravel. This is just the start, though, and there's more to learn.
We have some courses on real-time broadcasting with some practical applications that'll put everything nicely into context, like Build a Multi-room Realtime Chat with Livewire and Reverb.
Happy broadcasting!