Laravel Broadcasting Unveiled
The documentation page about broadcasting events in Laravel to a websocket client is a bit obscure: if you use the Pusher third-party service it will eventually work out-of-the-box (I don't know, haven't tried), but if you choose to setup your own websocket server you will find yourself looking for hints on Google. So, I write here some consideration to be indexed and found.
First of all, your main pitfall: the Redis + Socket.io method works, but you have to configure your queue subsystem (defining QUEUE_CONNECTION=redis
to your .env
file should be enough) and also run the queue listener (php artisan queue:listen
) alongside the effective websocket server (laravel-echo-server start
). Be sure to run all the processes with the right privileges.
The second pitfall: when using the default configuration for Redis, your channels are prefixed with yourappname_database_
. So, if you are pushing events to the foo
channel, of the client side you have to listen to yourappname_database_foo
channel. See the redis.options.prefix
option in your config/database.php
file.
This is enough to successfully run the code your already put together copy-pasting random stuff from documentation and StackOverflow before landing to this page.
For reference, here some code.
Javascript:
import Echo from "laravel-echo";
window.io = require('socket.io-client');
var echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
/*
Please note the dot '.' before the event name.
Cfr. https://laravel.com/docs/5.8/broadcasting#broadcast-name
*/
echo.channel('yourappname_database_foo.bar').listen('.event-name', (e) => {
doStuff(e);
});
Event code:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class EventName implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct()
{
}
public function broadcastOn()
{
/*
This will become yourappname_database_foo.bar
*/
return new Channel('foo.bar');
}
public function broadcastAs()
{
/*
The event name, without the initial dot '.'
*/
return 'event-name';
}
public function broadcastWith()
{
return [
'yourstuff' => 'foobar',
'otherstuff' => 'barbaz'
];
}
}