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'
        ];
    }
}
Show Comments