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',
],
永远不会触发事件监听器。我假设它进入队列然后需要重新触发事件,但我认为这不会发生,因为我的<?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));
}
}
侦听器没有填充任何数据来自该类构造函数。
EventServiceProvider:
var_dump
NewNotificationListener:
Notification Listener:
System.ComponentModel.DataAnnotations
此处为空,我的日志中没有任何内容,只有Sales
。
所以我的问题是,为什么这个以及如何在我需要的时候利用Queue时有一个Notification事件监听器。这是我做错了还是框架?
答案 0 :(得分:2)
快速回答:您在进行这些修改后是否重新启动了队列工作程序?
我的框上的NotificationSent
会在排队和处理时按预期触发和捕获。
当Laravel在NotificationSender
中点击这段代码时:
if ($notification instanceof ShouldQueue) {
return $this->queueNotification($notifiables, $notification);
}
它使用Queue Dispatcher对通知进行排队,并将其存储到队列中。当你的工作人员拿起它时,它会对命令进行反序列化,然后启动SendQueuedNotifications
。然后,该类将处理排队的通知,并处理队列(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
事件。
修改强>
这是我测试它的方式:
确保您的队列设置正确。我使用数据库队列,使用jobs / failed_jobs表组合。
创建文件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电子邮件):
<?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