how to broadcast event called by job class - laravel

In a Laravel project i am trying to broadcast a event named "closed" via pusher.
In my controller i am calling:
App\Jobs\Closing::dispatch();
My App\Jobs\Closing.php:
<?php
namespace App\Jobs;
use App\Jobs\Close;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class Closing implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(){}
public function handle()
{
$delay = mt_random(10,20);
Close::dispatch()->delay(now()->addSeconds($delay));
}
}
My app\Jobs\Close.php:
<?php
namespace App\Jobs;
use App\Events\Closed;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class Close implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(){}
public function handle()
{
event(new Closed());
}
}
My App\Events\Closed.php:
<?php
namespace App\Events;
use Illuminate\Queue\SerializesModels;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
class Closed implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(){}
public function broadcastOn()
{
return ['updates'];
}
public function broadcastAs()
{
return 'closed';
}
public function broadcastWith()
{
return ['message' => 'Is Closed!'];
}
}
At this point i need to explain two mandatory situations.
The first one is that i needed to create the job Close class as a job because i needed to delay the execution of the task close. And the only way i can see to make this "delay" is with a Job Class.
The second one is that i have chosen to implement "ShouldBroadcastNow" instead of "ShouldBroadcast" in the event Closed class because i don't want to queue the broadcasting.
Now the problem is that after running:
php artisan queue:work --tries=1
i get in the following output on Command Console:
Processing: App\Jobs\Closing
Processed: App\Jobs\Closing
Processing: App\Jobs\Close
Processing: App\Events\Closed
Failed: App\Events\Closed
Failed: App\Jobs\Close
The first thing that i find weird is that App\Events\Closed goes to queue despite the fact that it implements "ShouldBroadcastNow".
On laravel.log it seems that it occurred a BroadcastException at PusherBroadcaster.php.
But if in the Controller i do:
event(new App\Events\Closed());
the event is properly broadcast via pusher to the client browser.
What is going wrong?
Is there other way do delay the "close" without jobs?
The purpose is to have the following workflow:
1 - We have a event named "closing" an another event named "closed";
2 - We have a task named "close" that occurs "x" seconds after the event "closing", where "x" is a random number;
3 - After the execution of "close" task we broadcast the event "closed".
Thank you for your attention to my problem

Meanwhile i found this is a already known issue (https://github.com/laravel/framework/issues/16478).
It can be solved in two ways:
1 - editing the relevants php.ini files (in my case it was mamp/conf/php7.0.9/php.ini and mamp/bin/php/php7.0.9/php.ini) to point at the location of curl certificate;
2 - editing config/broadcasting.php (setting encrypted to false in pusher options).

Related

How to run MQTT subscribe in the background in Laravel

I am trying to put MQTT subscribe into a job saved in the database, but I get an error message that the job has failed instead of running for an infinite time. I would like to know if my approach is even possible and if there are any better alternatives to my problem.
My code
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use PhpMqtt\Client\Facades\MQTT;
class StartSub implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct()
{
//
}
public function handle()
{
$mqtt = MQTT::connection();
$mqtt->subscribe('topic', function (string $topic, string $message) {
echo sprintf('Received QoS level 1 message on topic [%s]: %s',
$topic, $message);
}, 1);
$mqtt->loop(true);
}
}
The answer is pretty simple. Although I do not know if it is 100% correct. After further investigation I found out that my code was failing because of time out. So i just had to put a public $timeout = 0;.

Undefined eager-loaded relationship when using Echo event broadcasting

I am using Laravel Echo in my project to broadcast events to the client-side. Everything is working correctly, however, I am having a problem in eager-loading the relationships of the model for the Event.
My Controller
$chat = new Chat;
$chat->user_id = $request->user_id;
$chat->message = $request->message;
$chat->save();
event( new GetMessages( $chat ));
My Event class:
class GetMessages implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $chats;
public function __construct($chats)
{
$this->chats = $chats;
}
public function broadcastOn()
{
return ['get-messages'];
}
public function broadcastAs()
{
return 'get-messages';
}
}
Here is my Laravel Echo
Echo.channel('get-messages')
.listen('.get-messages', (data) => {
console.log(data)
})
Everything is working fine as I expected, except getting the attachments from the Chat.
console.log(data.chats); // Undefined
Is there something I missed? Because as I tested the eager-loaded from the Event class itself, I can access the attachments in there.
public $chats;
public function __construct($chats)
{
$this->chats = $chats;
echo $chats->attachments // It's working in here, I can get the attachments
}
Hope I explain it well, Thank you in advance
Cheers!
Here is the console.log
Here is use, it's the default when I created the Event
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class GetMessages implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
...

Laravel dispatch queue always intermediately run

I am trying to dispatch jobs in Laravel into mysql. If I do
dispatch(new SendBroadcastSMS());
or
SendBroadcastSMS::dispatch()->delay(now()->addMinutes(2));
The job always runs intermediately. In my job, I set to sleep 30 seconds and my current controller/page that calls dispatch also waiting for 30 seconds and echo the job return. Why? It should run in the background via worker right? Or I misunderstand with the laravel queue?
My job is like below:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendBroadcastSMS implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct()
{
}
public function handle()
{
sleep(30);
echo "test";
// dd($this->sendSms("6281517777767","test message"));
//
}
}
my queue driver is database mysql and I also not receieved any row in job table
QUEUE_DRIVER=database
QUEUE_DRIVER is not the property you should set in your .env file.
The correct property is QUEUE_CONNECTION.
QUEUE_CONNECTION=database

How to load object into Laravel 5.5 Mailable?

I'm trying to test a mailable class for a Laravel 5.5 application, and have seemingly followed all the directions here.
I've been trying to preview my mailable in the browser, but for some reason the object that I pass to my mailable class is not passing correctly, and is showing as null from inside the mailable class even though I can see that it exists outside of it.
Here is the function in my web.php file that I'm using to test the mailable in the browser:
Route::get('/testingMailable', function () {
$review = App\EvaluationReview::find(6);
return new App\Mail\StartReview($review);
});
The object is populating as it should above, but when I try to view it inside the mailable class, it is null:
<?php
namespace App\Mail;
use App\EvaluationReview;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class StartReview extends Mailable
{
use Queueable, SerializesModels;
public $review;
public function __construct(EvaluationReview $review)
{
$this->$review = $review;
dd($this->review);//is null
}
public function build()
{
return $this->from('test#test.com')->view('startReview');
}
}
Does anyone know why the object is not getting passed into the mailable class?
You have a typo in your code.
Change:
$this->$review = $review;
To:
$this->review = $review;

Query builder in a queued command in Laravel 5

I'm using Laravel 5.0 and I've created a queued command with the Artisan CLI:
php artisan make:command SendEmail --queued
I need to use the DB::table() query builder method into this command, but I'm not able to make it work.
This is an excerpt of my code:
<?php namespace App\Commands;
use App\Commands\Command;
use DB;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldBeQueued;
class SendEmail extends Command implements SelfHandling, ShouldBeQueued {
use InteractsWithQueue, SerializesModels;
protected $message;
public function __construct($message)
{
$this->message = $message;
}
public function handle()
{
$data = DB::table('structures')->where('id', '=', '1')->first();
// $data is always empty even if database connection works outside the command!!! <-------------------
// no error exception is thrown
}
}
What am I doing wrong?
I found the error. I had to restart the supervisor queue in order the code to be correctly re-read:
supervisorctl
supervisor> restart myQueue

Resources