实现队列时,Laravel通知侦听器无用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现队列时,Laravel通知侦听器无用相关的知识,希望对你有一定的参考价值。
Laravel版本:5.5。*
php版本:7.1。*
根据文档https://laravel.com/docs/5.5/notifications,订阅Notification事件应该非常简单。我已按照文档中的步骤操作,但我的通知实现了ShouldQueue
,并且它们没有正确填充事件侦听器。我想知道问题似乎是in the framework code。
请注意,在框架github(右上方链接)中,new EventsNotificationSent($notifiable, $notification, $channel, $response)
仅从sendToNotifiable
函数触发,而sendNow
函数仅从send
函数触发。 public function send($notifiables, $notification)
{
$notifiables = $this->formatNotifiables($notifiables);
if ($notification instanceof ShouldQueue) {
return $this->queueNotification($notifiables, $notification);
}
return $this->sendNow($notifiables, $notification);
}
函数本身就是这样的:
if ($notification instanceof ShouldQueue) {
也就是说,正如它向我读到的那样,如果是queueNotification
的情况,事件将不会触发,因为NotificationSent
从不触发事件监听器。我假设它进入队列然后需要重新触发事件,但我认为这不会发生,因为我的 protected $listen = [
'IlluminateNotificationsEventsNotificationSent' => [
'AppListenersNewNotificationListener',
],
监听器没有填充来自该类构造函数的任何数据。
EventServiceProvider:
<?php
namespace AppListeners;
use IlluminateNotificationsEventsNotificationSent;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use AppJobsSendEmailForNotifications;
use IlluminateSupportFacadesLog;
class NewNotificationListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
public function handle(NotificationSent $event)
{
Log:info('Notification Listener:'.' '.var_dump($event));
SendEmailForNotifications::dispatch($event->notification)->delay(now()->addMinutes(10));
}
}
NewNotificationListener:
var_dump
Notification Listener:
在这里是空的,我的日志中什么都没有,只是NotificationSent
。
所以我的问题是,为什么这样,我如何在我需要的时候利用Queue时有一个Notification事件监听器。这是我做错了还是框架?
快速回答:进行这些修改后,您是否重新启动了队列工作程序?
我的盒子上的NotificationSender
在排队和处理时按预期被触发和捕获。
当Laravel在if ($notification instanceof ShouldQueue) {
return $this->queueNotification($notifiables, $notification);
}
中遇到这段代码时:
SendQueuedNotifications
它使用Queue Dispatcher对通知进行排队,并将其存储到队列中。当你的工作人员拿起它时,它会对命令进行反序列化,然后启动source。然后,该类将处理排队的通知,并处理队列(public function handle(ChannelManager $manager)
{
$manager->sendNow($this->notifiables, $this->notification, $this->channels);
}
):
ChannelManager
而source这样做(public function sendNow($notifiables, $notification, array $channels = null)
{
return (new NotificationSender(
$this, $this->app->make(Bus::class), $this->app->make(Dispatcher::class))
)->sendNow($notifiables, $notification, $channels);
}
):
sendNow
你去吧NotificationSender
中的NotificationSent
被称为。应该在此函数中调用app/Listeners/TestListener.php
事件。
编辑
这是我测试它的方式:
- 确保您的队列设置正确。我使用数据库队列,使用jobs / failed_jobs表组合。
- 创建文件
<?php namespace AppListeners; use IlluminateNotificationsEventsNotificationSent; class TestListener { public function handle(NotificationSent $event) { Log::info(get_class($event)); } }
app/Providers/EventServiceProvider.php
- 编辑
<?php namespace AppProviders; use AppListenersTestListener; use IlluminateNotificationsEventsNotificationSent; use LaravelLumenProvidersEventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { /** * The event listener mappings for the application. * * @var array */ protected $listen = [ NotificationSent::class => [ TestListener::class ] ]; }
<?php namespace AppNotificationsUsers; use AppNotificationsNotification; use IlluminateBusQueueable; use IlluminateContractsQueueShouldQueue; use IlluminateNotificationsChannelsMailChannel; use IlluminateNotificationsMessagesMailMessage; class WelcomeNotification extends Notification implements ShouldQueue { use Queueable; public function via($notifiable) { return [MailChannel::class]; } public function toMail($notifiable) { return (new MailMessage()) ->line('Hello'); } }
- 创建虚拟通知(发送Hello电子邮件):
php artisan queue:work
- 重启队列工作者。我只是重新启动我的
$user->notify(new WelcomeNotification());
。 - 发送通知
laravel.log
- 检查
NotificationSent
,您应该在那里打印[2018-03-06 09:51:02] production.INFO: IlluminateNotificationsEventsNotificationSent
的班级名称。 qazxswpoi
以上是关于实现队列时,Laravel通知侦听器无用的主要内容,如果未能解决你的问题,请参考以下文章