-
Create an Event:
php artisan make:event DocumentEvent
-
Create Listener
php artisan make:listener DocumentListener --event=DocumentEvent
-
inside DocumentEvent
class DocumentEvent implements ShouldQueue ,ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; /** * Create a new event instance. */ public function __construct(public $count) { } /** * Get the channels the event should broadcast on. * * @return array<int, \Illuminate\Broadcasting\Channel> */ public function broadcastOn(): Channel { return new Channel('notification'); } }
-
Inside Listener
class DocumentListener implements ShouldQueue, ShouldHandleEventsAfterCommit { use InteractsWithQueue; public $queue = "high"; /** * Create the event listener. */ public function __construct() { // } /** * Handle the event. */ public function handle(DocumentEvent $event): void { for ($i=0; $i < $event->count; $i++) { User::create([ 'name' => fake()->name(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => Hash::make("password") ]); } } public function failed(DocumentEvent $event , Throwable $th) { report($th); } public function retryUntill(): DateTime { return now()->addMinute(3); } }
-
Register Event and Listener inside EventServiceProvider
protected $listen = [ Registered::class => [ SendEmailVerificationNotification::class, ], DocumentEvent::class => [ DocumentListener::class ], ];
-
set up Channel Route inside Channel Route in Laravel router folder
Broadcast::channel('notification', function () { return true; // Define your authentication logic here });
-
in bootstrap.js, we export WebsocketEcho for reusability in other Reactjs pages you want realtime Environment
- make sure each env is configured successfull in .env file for each key
window.Pusher = Pusher; export const WebSocketEcho = new Echo({ broadcaster: 'pusher', key: import.meta.env.VITE_PUSHER_APP_KEY, cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1', wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443, forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', enabledTransports: ['ws', 'wss'], });
-
Now , feel free to design any realtime env , mine was so simple overview
- when user click a link , application generate number of user into db , and this scenario is queued in queed Jobs ,
- App through websocket send notification to browser without any page refresh from user
- this happen automatically and number of users from db is calculated by aggregate function from sql query
- Good , now you understand the scenario , feel free to Think big on any realtime situation
Handle in this way in Javascript file
useEffect(()=> { const NotificationChannel = WebSocketEcho.channel("notification"); NotificationChannel.listen("DocumentEvent", (event)=> { console.log(event); }) return ()=> { NotificationChannel.stopListening("DocumentEvent"); } }, []);
public function Store(Request $request)
{
// $file = $request->file("filename");
// $filepath = $file->storeAs("temp",'users.csv');
// dispatch(new ImportCsvFile($filepath));
// dispatch Batches of Jobs
$batch = Bus::batch([
new ImportCsvFileWithBaches(1, 5),
new ImportCsvFileWithBaches(6, 7),
new ImportCsvFileWithBaches(7, 9),
new ImportCsvFileWithBaches(9, 14),
new ImportCsvFileWithBaches(15, 16),
])
->then(function (Batch $batch) {
echo "JOB COMLETE :" . $batch->progress() . "\n\n";
// mrwilbroadmark123@gmail.com
JobAnalysisEvent::dispatch($batch->progress(),
$batch->totalJobs,
"success",
"Data successfull saved to database",
true
);
})
->catch(function (Batch $batch, Throwable $e) {
// First Job failure detected ...
JobAnalysisEvent::dispatch($batch->progress(),
$batch->totalJobs,
"danger",
"Something went wrong , some data not saved!",
true
);
})
->finally(function (Batch $batch) {
// The batch has finnished executing ...
})
->onQueue("importcsv")
// ->name("ImportCsv")
->dispatch();
// dd($batch);
return back();
}
try {
$file = $request->file('filename');
$filepath = $file->storeAs("temp", 'userfile.csv');
$fullpath = storage_path('app/' . $filepath);
$rows = SimpleExcelReader::create($fullpath)
->getRows();
$userChunks = $rows->chunk(30);
foreach ($userChunks as $chunk) {
ImportLargeCsvFileWithBatch::dispatch($chunk->toArray())
->onQueue("importcsv");
}
return back();
} catch (\Throwable $th) {
dd($th);
}