Laravel版本:5.5。*
PHP版本:7.1。*
根据文档https://laravel.com/docs/5.5/notifications,订阅Notification事件应该非常简单。我已按照文档中的步骤操作,但我的通知实现了ShouldQueue
,并且它们没有正确填充事件侦听器。我想知道问题似乎是in the framework code。
请注意,在框架github(右上方链接)中,new Events\NotificationSent($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 = [
'Illuminate\Notifications\Events\NotificationSent' => [
'App\Listeners\NewNotificationListener',
],
监听器没有填充来自该类构造函数的任何数据。
EventServiceProvider:
<?php
namespace App\Listeners;
use Illuminate\Notifications\Events\NotificationSent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Jobs\SendEmailForNotifications;
use Illuminate\Support\Facades\Log;
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
事件。
编辑
这是我测试它的方式:
<?php
namespace App\Listeners;
use Illuminate\Notifications\Events\NotificationSent;
class TestListener
{
public function handle(NotificationSent $event)
{
\Log::info(get_class($event));
}
}
app/Providers/EventServiceProvider.php
<?php
namespace App\Providers;
use App\Listeners\TestListener;
use Illuminate\Notifications\Events\NotificationSent;
use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
NotificationSent::class => [
TestListener::class
]
];
}
<?php
namespace App\Notifications\Users;
use App\Notifications\Notification;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Channels\MailChannel;
use Illuminate\Notifications\Messages\MailMessage;
class WelcomeNotification extends Notification implements ShouldQueue
{
use Queueable;
public function via($notifiable)
{
return [MailChannel::class];
}
public function toMail($notifiable)
{
return (new MailMessage())
->line('Hello');
}
}
php artisan queue:work
$user->notify(new WelcomeNotification());
。laravel.log
NotificationSent
,您应该在那里打印[2018-03-06 09:51:02] production.INFO: Illuminate\Notifications\Events\NotificationSent
的班级名称。
qazxswpoi