不触发没有通道的排队作业?

Not fire queued jobs with no channels?

有什么方法可以阻止排队的作业在频道为空时触发广播事件吗?基本上我注意到的是,如果 broadcastOn returns [] 没有套接字推送会关闭,它仍然会进行排队作业。有什么方法可以让排队的作业仅在 broadcastOn returns 一个至少包含一个元素的数组时创建?

您必须进行一些手动子类化才能完成这项工作。排队作业是在 Illuminate\Events\Dispatcher.

broadcastEvent 方法中创建的
protected function broadcastEvent($event)
{
    if ($this->queueResolver) {
        $connection = $event instanceof ShouldBroadcastNow ? 'sync' : null;

        $queue = method_exists($event, 'onQueue') ? $event->onQueue() : null;

        $this->resolveQueue()->connection($connection)->pushOn($queue, 'Illuminate\Broadcasting\BroadcastEvent', [
            'event' => serialize(clone $event),
        ]);
    }
}

如果 $event->broadcastOn return 数组至少包含一个元素,您可以在此处添加检查以仅将作业推送到队列中。

子类化后,您将需要使用新的调度程序来触发事件。您可以为此创建一个新的服务提供者并将其绑定到容器。我不确定您是否可以覆盖在 Illuminate\Events\EventServiceProvider 中创建的现有 events 实例,但您绝对可以创建一个新实例。

public function register()
{
    $this->app->singleton('events-custom', function ($app) {
        return (new App\Provides\CustomDispatcher($app))->setQueueResolver(function () use ($app) {
            return $app->make('Illuminate\Contracts\Queue\Factory');
        });
    });
}

如果您使用的是 Events facade,请务必同时更新您的配置文件以指向一个新的 Facade,该新 Facade return是您新的 CustomDispatcher 的关键。不幸的是,events() 辅助函数仍将 return 原来的 Dispatcher。我不相信那可以被覆盖。如果你能以某种方式覆盖由 Illuminate\Events\EventServiceProvider 设置的现有 events 键,那么你就完成了。

在 Laravel 5.4 中,您现在似乎可以为事件添加一个新方法,broadcastWhen。所有需要完成的事情:

public function broadcastOn() {
    return [];
}

public function broadcastWith() {
   return count($this->broadcastOn()) > 0;
}

您可以在 source code 中阅读有关如何处理 broadcastWhen 的更多信息。

Check if event should be broadcasted by condition.