问题描述
Laravel版本:5.5.*
Laravel Version: 5.5.*
PHP版本:7.1.*
PHP Version: 7.1.*
根据文档 https://laravel.com/docs/5.5/notifications订阅Notification事件应该非常简单.我已经按照文档中的步骤进行操作,但是我的Notifications实现了 ShouldQueue
,并且它们没有正确填充事件侦听器.我想知道问题是否是 在框架代码中 .
According to the docs https://laravel.com/docs/5.5/notifications it should be super simple to subscribe to Notification events. I've followed the steps in the docs, but my Notifications implement ShouldQueue
and they weren't properly populating the event listener. I'm wonder if the issue seems to be in the framework code.
请注意,在github框架(右上方)中,仅从 sendToNotifiable new Events \ NotificationSent($ notifiable,$ notification,$ channel,$ response)
/code>函数,而该函数仅从 sendNow
函数中触发. send
函数本身就是这样的:
Notice that in the framework github (linked right above), that new Events\NotificationSent($notifiable, $notification, $channel, $response)
is only fired from the sendToNotifiable
function, which in turn is only fired from the sendNow
function. The send
function itself, is like this:
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
侦听器未填充任何 any 来自该类构造函数的数据.
That is, as it reads to me, the event will not fire if it is a case of if ($notification instanceof ShouldQueue) {
as queueNotification
never triggers an event listener. I assume it goes into the queue and then will need to re-trigger the event, but I don't think this is happening, because my NotificationSent
listener isn't populated with any data from that class constructor.
EventServiceProvider:
EventServiceProvider:
protected $listen = [
'Illuminate\Notifications\Events\NotificationSent' => [
'App\Listeners\NewNotificationListener',
],
NewNotificationListener:
NewNotificationListener:
<?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));
}
}
var_dump
这里是空的,我的日志中什么也没有,只是 Notification Listener:
.
var_dump
here is empty, I get nothing in my log, just Notification Listener:
.
所以我的问题是,为什么要这样做?如何在需要使用队列的同时使用Notification事件侦听器?是我做错了什么还是框架?
So my question is, why is this and how can I have a Notification event listener while leveraging the Queue as I need to do. Is it something I am doing wrong or is it the framework?
推荐答案
快速解答:进行这些修改后,您是否重新启动了队列工作器?
我的盒子上的 NotificationSent
在排队和处理时会按预期触发并捕获.
The NotificationSent
on my box is triggered and captured as expected when it's being queued and handled.
Laravel在 NotificationSender
中击中这段代码时:
When Laravel hit this piece of code in NotificationSender
:
if ($notification instanceof ShouldQueue) {
return $this->queueNotification($notifiables, $notification);
}
它使用队列调度程序将通知排队,并将其存储到您的队列中.当您的工作人员拿起它时,它会反序列化命令,然后启动 SendQueuedNotifications
.然后,此类将处理排队的通知,并处理队列(源):
It queues the notification using the Queue Dispatcher and store it into your queue. And when your worker pick it up, it unserialise the command, and launches SendQueuedNotifications
. This class will then handle the queued notifications, and handle the queue (source):
public function handle(ChannelManager $manager)
{
$manager->sendNow($this->notifiables, $this->notification, $this->channels);
}
然后 ChannelManager
进行此操作(源):
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);
}
然后您就去了.调用 NotificationSender
中的 sendNow
. NotificationSent
事件应在此函数中调用.
And there you go. The sendNow
in NotificationSender
is called. The NotificationSent
event should be called in this function.
修改
这是我测试的方式:
-
确保已正确设置队列.我使用一个数据库队列,与jobs/failed_jobs表组合.
Make sure your queue has been set up correctly. I use a database queue, with jobs/failed_jobs table combo.
创建文件 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
]
];
}
创建虚拟通知(发送Hello电子邮件):
Create a dummy notification (send an Hello email):
<?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队列:工作
.
Restart your queue worker. I simply restart my php artisan queue:work
.
发送通知
$user->notify(new WelcomeNotification());
检查 laravel.log
,您应该在其中打印 NotificationSent
的类名.
Check laravel.log
, you should have the class name of NotificationSent
printed there.
[2018-03-06 09:51:02] production.INFO: Illuminate\Notifications\Events\NotificationSent
这篇关于Laravel通知侦听器在实现队列时无用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!