在"地平线"文档中,它提到可以将自定义标签添加到排队的事件侦听器中。但是,我找不到任何方法,其中包含所需的数据。给定的示例使用类型模具将相关模型从服务容器中拉出并将其分配给构造函数中的实例变量,然后在tags()
方法中使用该实例变量来获取有关要操作的特定模型实例的数据。/p>
在排队的事件侦听器中执行此操作时,它行不通。实际上,由于模型在执行时被序列化和"重新水合",构造函数似乎根本没有被调用。因此,构造函数中的键入标题什么都不做,并且tags()
似乎在handle()
之前调用,因此我无法访问我正在听的事件对象。
有人知道我如何在这种情况下在标签中获取事件信息吗?
更新:
在控制器中称为事件:
event(new PostWasCreated($user, $post));
事件 postwascreated :
<?php
namespace AppEvents;
use IlluminateBroadcastingChannel;
use IlluminateQueueSerializesModels;
use IlluminateBroadcastingPrivateChannel;
use IlluminateBroadcastingPresenceChannel;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateContractsBroadcastingShouldBroadcast;
use AppUser;
use AppPost;
class PostWasCreated
{
use InteractsWithSockets, SerializesModels;
public $user;
public $post;
public function __construct(User $user, Post $post)
{
$this->user = $user;
$this->post = $post;
}
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
听众 postwascreatednotificationendend :
<?php
namespace AppListeners;
use AppEventsPostWasCreated;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
class PostWasCreatedNotificationSend implements ShouldQueue
{
protected $event;
public $queue = 'notifications'; // Adds queue name
public function __construct(PostWasCreated $event)
{
$this->event = $event;
// Does NOT add queue tag
$this->queueTags = ['post: ' . $this->event->post->id];
}
public function tags()
{
return $this->queueTags;
}
public function handle(PostWasCreated $event)
{
// handle event here...
}
}
问题是$this->queueTags
永远不会分配,因此该排队的侦听器中没有标签...(虽然出现了队列名称,但我们也需要标签(。
horizon甚至在将作业推到队列之前收集任何标签,因此我们不能依靠作业在执行之前不知道的任何值。在这种情况下,该作业知道User
和Post
,因为我们通过它们来初始化事件。
对于排队的侦听器,标记系统检查事件对象和侦听器类上的标签。如问题所述,无法在侦听器上使用动态数据设置标签,因为处理程序在Horizon之后执行将作业从队列中弹出。我们只能在侦听器上声明静态标签,即Horizon将与事件中的标签合并*:
class PostWasCreatedNotificationSend implements ShouldQueue
{
...
public function tags()
{
return [ 'listener:' . static::class, 'category:posts' ];
}
}
使用事件对象,Horizon尝试自动为任何雄辩的模型成员生成标签。例如,Horizon将为PostWasCreated
事件创建以下标签:
-
$event->user
&rarr;AppUser:<id>
-
$event->post
&rarr;AppPost:<id>
我们可以覆盖此行为,并通过定义上述tags()
方法来告诉Horizon为事件设置哪个标签:
class PostWasCreated
{
...
public function tags()
{
return [ 'post:' . $this->post->id ];
}
}
请注意,如果事件或在撰写本文时,Horizon不会自动为模型创建标签。侦听器手动提供标签。
问题是
$this->queueTags
从未分配,因此该排队的侦听器中没有标签...(虽然显示了队列名称,但我们也需要标签(。
Horizon不会为每个属性创建标签;自动标记仅适用于包含雄辩模型的人(通常不适合听众(。
*如果事件也用于广播(它实现了ShouldBroadcast
(,则创建的用于发布消息的附加作业不会继承侦听器提供的任何标签。