【发布时间】:2016-10-27 04:57:59
【问题描述】:
当频道为空时,是否有任何方法可以抑制排队的作业触发广播事件?基本上我注意到的是,如果broadcastOn 返回[],则不会关闭任何套接字推送,但它仍然会进行排队工作。有没有办法让队列作业仅在broadcastOn 返回一个包含至少一个元素的数组时创建?
【问题讨论】:
当频道为空时,是否有任何方法可以抑制排队的作业触发广播事件?基本上我注意到的是,如果broadcastOn 返回[],则不会关闭任何套接字推送,但它仍然会进行排队工作。有没有办法让队列作业仅在broadcastOn 返回一个包含至少一个元素的数组时创建?
【问题讨论】:
您必须进行一些手动子类化才能完成这项工作。排队作业是在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 返回包含至少一个元素的数组时才将作业推送到队列中。
一旦子类化,您将需要使用新的调度程序来触发事件。您可以为此创建一个新的服务提供者并将其绑定到容器。我不确定你是否可以覆盖在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');
});
});
}
如果您正在使用事件门面,请务必同时更新您的配置文件以指向一个新门面,该门面将密钥返回到您的新 CustomDispatcher。不幸的是,events() 辅助函数仍将返回原始 Dispatcher。我不相信它可以被覆盖。如果你能以某种方式覆盖由Illuminate\Events\EventServiceProvider 设置的现有events 密钥,那么你就大功告成了。
【讨论】:
似乎在 Laravel 5.4 中,您现在可以为事件添加一个新方法,broadcastWhen。所有需要做的:
public function broadcastOn() {
return [];
}
public function broadcastWith() {
return count($this->broadcastOn()) > 0;
}
您可以在source code 中阅读有关如何处理broadcastWhen 的更多信息。
检查事件是否应该按条件广播。
【讨论】: