michaeldzjap's avatar

Setting up event broadcasting for Lumen app (using log driver initially)

I am trying to integrate the event broadcasting mechanism in a Lumen 5.4 app. I thought it would be a good idea to initially test it with the log driver. I think I've managed to set up everything correctly. However, when I fire the event nothing seems to be happening, so I guess my setup is still incomplete.

What I have done so far:

  • Copied the broadcasting.php config file from a fresh Laravel 5.4 project to my Lumen project and $app->configure('broadcasting'); in bootstrap/app.php
  • Registered BroadcastServiceProvider.php in bootstrap/app.php using $app->register(\Illuminate\Broadcasting\BroadcastServiceProvider::class);
  • Added a channels.php in the app\Http folder and added the line require __DIR__.'/../app/Http/channels.php'; in bootstrap/app.php
  • Specified a BROADCAST_DRIVER=log var in my .env file

The event I am trying to broadcast looks like:

<?php

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\User;

class TestBroadcast extends Event implements ShouldBroadcast
{
    use InteractsWithSockets;

    private $user;

    public $message;

    /**
     * Create a new event instance.
     *
     * @param  User $user
     * @param  string $message
     * @return void
     */
    public function __construct(User $user, string $message)
    {
        $this->user = $user;
        $this->message = $message;
    }

   /**
     * Get the channels the event should broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        $id = $this->user->id;

        return new PrivateChannel("test.{$id}");
    }

    public function onQueue()
    {
        return 'listeners';
    }
}

The 'listeners' queue is just a custom queue I defined for dispatching my events. I am sure that is running correctly, as I use it to dispatch other events from my app without a problem.

In channels.php I've added the following:

$app[Illuminate\Contracts\Broadcasting\Factory::class]
    ->channel('test.{userID}', function ($user, $userID) {
        return $user->id === $userID;
    });

To test it out, I've added a route in routes.php:

$app->get('/test-broadcasting', function () use ($app) {
    event(new \App\Events\TestBroadcast(
        \App\User::where('id', 17)->first(),
        'Hey now!'
    ));
});

Visiting this route from a browser does nothing though. It doesn't throw any errors, but nothing gets logged either. I've also put a dd() in the broadcastOn() function of my event to see if that gets called at all and it doesn't. I'm not sure what is missing still... Any ideas?

0 likes
2 replies
michaeldzjap's avatar

So it turns out onQueue()is not the way to specify the queue the event should be pushed on. Read this in the Laravel: Up and Running book, but that just seems plain wrong. Instead, you need to specify a public $broadcastQueue property on the event, as per the Laravel documentation.

I can see the event is placed in my the jobs table of my database with the correct queue name now. So that is a good sign. Not quite sure why the queue is not processed though.

michaeldzjap's avatar
michaeldzjap
OP
Best Answer
Level 1

I finally figured this out. It turns out that you shouldn't register BroadcastServiceProvider and configure broadcasting.php yourself in bootstrap/app.php. This is already done automatically in the Lumen source. Doing this yourself messes things up. Placing broadcasting.php in the config folder is all you need to do.

I find this quite confusing, as I've noticed that for other things (e.g. placing an auth.php in config or using MailServiceProvider) it is necessary to do the registering/configuring yourself in bootstrap/app.php. I wish the Lumen documentation would be a little more clear on this...

1 like

Please or to participate in this conversation.