我有一个工作网站,用户可以关注公司,然后他会在新工作时收到通知,所以我做的是以下内容:
我创建了一个名为JobNotification的模型,每当公司创建新工作时,我创建一个工作通知,我存储company_id,job_id和生成的文本,因此这个工作通知将被发送给用户,
我接下来要做的是创建一个名为SendJobNotification的作业,并在创建JobNotification后调度它,SendJobNotification将获取跟随该公司的用户并插入user_id和job_notification_id,这样当用户再次登录时,他将会看到通知。
所以问题是,还有更好的方法吗?也许使用事件? 我不想使用队列:在服务器中监听以运行队列,用户提取也需要花费很多时间。 这是我的SendJobNotification工作代码:
namespace App\Jobs;
use App\AccountJobNotification;
use App\Jobs\Job;
use App\Account;
use App\JobNotification;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Company;
class SendJobNotification extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
protected $notification;
public function __construct(JobNotification $notification)
{
$this->notification = $notification;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$users = Company::find($this->notification->company_id)->followers()->get();
foreach ($users as $user)
{
$job_notification = new AccountJobNotification();
$job_notification->user_id = $user->id;
$job_notification->job_notification_id = $this->notification->id;
$job_notification->save();
}
}
}
请注意,我不是在做实时通知。
答案 0 :(得分:3)
是的,你可以通过使用事件和监听器来实现。
我会这样做:
在您的控制器中,触发事件:
Event::fire(new JobCreated($job));
然后添加一个事件(JobCreated.php)和一个监听器(AddNotifications.php):
在您的事件文件夹中创建:JobCreated.php:
<?php
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class JobCreated extends Event
{
public function __construct($job)
{
$this->job_id=$job->id;
$this->company_id=$job->company_id;
}
}
在您的侦听器文件夹中,创建Addnotifications.php:
<?php
namespace App\Listeners;
use App\Events\JobCreated;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class AddNotifications
{
public function handle(JobCreated $event)
{
$company_id=$event->company_id;
$job_id=$event->job_id;
your handle code......
}
}
不要忘记将两者都包含在providers文件夹中的EventServiceProvider.php中:
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'App\Events\JobCreated' => [
'App\Listeners\AddNotifications'
],
];
}
答案 1 :(得分:2)
@Ferran的回答是正确的。要在队列中添加此事件,您必须实现如下所示的ShouldQueue接口。
<?php
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Queue\ShouldQueue;
class JobCreated extends Event implements ShouldQueue
{
public function __construct($job)
{
$this->job_id=$job->id;
$this->company_id=$job->company_id;
}
}
有效地运行队列。使用queue :: work as并将其作为守护进程运行,如下所示
php artisan queue:work connection-name --daemon
在linux架构上添加&#34;&gt; / dev / null 2&gt;&amp; 1&#34;在结束代码命令,无需等待即可运行它。
php artisan queue:work beanstalkd --sleep=3 --tries=3 --daemon > /dev/null 2>&1 &
这里beanstalkd是队列驱动程序或者你可以使用supervisor。使用以下链接获取更多信息
答案 2 :(得分:1)
由于您已经要求一种方法来发送不需要队列工作者的通知(我认为这是正确的方法,BTW),这里有一种方法可以使用数据库通知。< / p>
您已经使用事件侦听器/处理程序获得了示例的答案,因此这里有一种使用本机Eloquent事件和服务提供程序的方法。
除此之外:服务提供商不是必需的,但我想包含所有服务提供商 我的模特活动,所以我不会把头发拉过来检查 试图找到错误的创建/删除事件的模型
你需要先做一点设置:
php artisan make:provider JobListingServiceProvider
php artisan make:notification JobListingWasCreated
php artisan notifications:table
php artisan migrate
...您需要在config/app.php
中修改提供商列表,以包含新的提供商...
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\JobListingServiceProvider::class, //<-- New one
JobListingServiceProvider &lt; - 服务提供商
public function boot(){
JobListing::created(function($listing){
$newJobListing = new JobListingWasCreated($listing);
$listing->company->followers()->orderBy('id')->chunk(50, function($users) use ($newJobListing){
foreach($users as $user)
{
$user->notify($newJobListing);
}
});
});
}
我在那里使用chunk()
代替each()
,因为您可能正在处理可能数千个用户记录(正如文档所建议的那样),并且那里有orderBy('id')
因为{ {1}}要求您的构建器中包含chunk()
子句。
JobListingWasCreated &lt; - 通知
orderBy
因为我们正在收听Eloquent事件,所以在没有“发出”通知的情况下创建工作列表是不可能的(在这种情况下意味着它们已保存到数据库中,尽管我再次建议使用队列,如果您要进行网络交易,如发送电子邮件或Slacks)。
将职位列表添加到公司时,我的本地计算机花了大约3秒钟为1542个用户创建通知。如果某人等待创建职位列表的时间太长,那么您将 使用队列。如果您使用电子邮件或Slack,则每个通知的用户需要更长的时间。
如果您想重新创建类似的条件,这是我的数据库播种器代码:
protected $listing;
public function __construct(JobListing $listing)
{
$this->listing = $listing;
}
public function via($notifiable)
{
return ['database'];
}
public function toArray($notifiable)
{
return [
'listing_id' => $this->listing->id,
'company_id' => $this->listing->company->id
];
}
另外,我的用户/公司模型清晰明了:
$users = factory(App\User::class, 10000)->create();
$companies = factory(App\Company::class, 300)->create();
$users->each(function($user) use($companies){
$ids = $companies->random(rand(10, 80))->pluck('id')->all();
$user->companies()->sync($ids);
});
class User extends Authenticatable
{
use Notifiable;
public function companies()
{
return $this->belongsToMany(Company::class);
}
}
...以及用户和公司之间的多对多数据透视表:
class Company extends Model
{
public function addJobListing($listingTitle)
{
$this->jobListings()->save(
new JobListing(['title' => $listingTitle])
);
}
public function jobListings()
{
return $this->hasMany(JobListing::class);
}
public function followers()
{
return $this->belongsToMany(User::class);
}
}