Sum*_*per 2 events laravel laravel-5.5
Laravel 版本:5.5.*
PHP 版本:7.1.*
根据文档https://laravel.com/docs/5.5/notifications订阅通知事件应该非常简单。我已经按照文档中的步骤操作,但是我的通知实现了ShouldQueue
并且它们没有正确填充事件侦听器。我想知道问题是否出在框架代码中。
请注意,在 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);
}
Run Code Online (Sandbox Code Playgroud)
也就是说,它读取对我来说,事件不会火,如果它是的情况下,if ($notification instanceof ShouldQueue) {
作为queueNotification
从来没有触发事件侦听器。我假设它进入队列,然后需要重新触发事件,但我认为这不会发生,因为我的NotificationSent
侦听器没有填充来自该类构造函数的任何数据。
事件服务提供者:
protected $listen = [
'Illuminate\Notifications\Events\NotificationSent' => [
'App\Listeners\NewNotificationListener',
],
Run Code Online (Sandbox Code Playgroud)
新通知监听器:
<?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));
}
}
Run Code Online (Sandbox Code Playgroud)
var_dump
这里是空的,我的日志中什么也没有,只有Notification Listener:
.
所以我的问题是,为什么会这样,我如何在需要时利用队列的同时拥有一个通知事件侦听器。是我做错了什么还是框架?
快速回答:您在进行这些修改时是否重新启动了队列工作器?
将NotificationSent
在我的箱子被触发,捕获时,它的排队和处理的预期。
当 Laravel 在 中遇到这段代码时NotificationSender
:
if ($notification instanceof ShouldQueue) {
return $this->queueNotification($notifiables, $notification);
}
Run Code Online (Sandbox Code Playgroud)
它使用 Queue Dispatcher 对通知进行排队,并将其存储到您的队列中。当您的工作人员拿起它时,它会反序列化命令,并启动SendQueuedNotifications
. 然后这个类将处理排队的通知,并处理队列(源):
public function handle(ChannelManager $manager)
{
$manager->sendNow($this->notifiables, $this->notification, $this->channels);
}
Run Code Online (Sandbox Code Playgroud)
而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);
}
Run Code Online (Sandbox Code Playgroud)
你去吧。将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));
}
}
Run Code Online (Sandbox Code Playgroud)编辑 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
]
];
}
Run Code Online (Sandbox Code Playgroud)创建一个虚拟通知(发送一封 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');
}
}
Run Code Online (Sandbox Code Playgroud)重新启动您的队列工作器。我只是重新启动我的php artisan queue:work
.
发送通知
$user->notify(new WelcomeNotification());
Run Code Online (Sandbox Code Playgroud)检查laravel.log
,您应该在NotificationSent
那里打印类名。
[2018-03-06 09:51:02] production.INFO: Illuminate\Notifications\Events\NotificationSent
Run Code Online (Sandbox Code Playgroud) 归档时间: |
|
查看次数: |
3357 次 |
最近记录: |