Laravel Reverb & Echo — Questions et réponses pour l'entretien

DEV - 07/03
1️⃣ WebSocket ici ? HTTP est-il possible de le faire ? সহজ উত্তর: কল্পনা করো তুমি তোমার বন্ধুকে চিঠি...

1️⃣ WebSocket ici ? HTTP est-il possible de le faire ?

Voici ce qui suit :

কল্পনা করো তুমি তোমার বন্ধুকে চিঠি পাঠাচ্ছো। HTTP চিঠির মতো :

তুমি → চিঠি পাঠালে → বন্ধু পড়লো → জবাব দিলো → শেষ (প্রতিবার নতুন চিঠি = নতুন connexion)
Entrer en mode plein écran Quitter le mode plein écran

WebSocket est également disponible :

তুমি → ফোন করলে → লাইন খোলা রইলো → যেকোনো সময় কথা বলো (একবার connect = সবসময় connecté)
Entrer en mode plein écran Quitter le mode plein écran

HTTP:

Navigateur →→→ Requête →→→ Navigateur du serveur ←←← Réponse ←←← Serveur (connexion বন্ধ !)
Entrer en mode plein écran Quitter le mode plein écran

WebSocket:

Navigateur ←——————————————→ Serveur (ouvert en cours) যেকোনো সময় données দুইদিক থেকেই যেতে পারে
Entrer en mode plein écran Quitter le mode plein écran

2️⃣ Laravel Reverb ici? Pusher থেকে কীভাবে আলাদা? সহজ উত্তর: Pusher হলো ভাড়া করা ফোন সার্ভিসের মতো — তুমি টাকা দাও, তারা সব gérer করে। Reverb হলো নিজের ফোন টাওয়ার বানানোর মতো — তোমার VPS-এ নিজেই চলে, কাউকে টাকা দিতে হয় না। Poussoir :

তোমার App → Pusher এর Server (বাইরে) → Utilisateur (মাসে টাকা লাগে 💰)
Entrer en mode plein écran Quitter le mode plein écran

Réverbération :

তোমার App → তোমার নিজের Serveur → Utilisateur (একদম ফ্রি! 🎉)
Entrer en mode plein écran Quitter le mode plein écran
# Reverb install et composer require laravel/reverb php artisan reverb:install # চালানো php artisan reverb:start
Entrer en mode plein écran Quitter le mode plein écran

3️⃣ Laravel Echo ici? সহজ উত্তর: Echo হলো তোমার কানের মতো 👂 Reverb Server কথা বলে — Echo সেটা শোনে এবং তোমার navigateur-এ দেখায়।

javascript // Echo ছাড়া (কঠিন) : const socket = new WebSocket('ws://localhost:8080'); socket.onmessage = function(event) { const data = JSON.parse(event.data); if(data.event === 'MessageSent') { // কাজ করো } }; // Echo দিয়ে (সহজ): Echo.private('chat.1') .listen('MessageSent', (e) => { // সরাসরি কাজ করো! Echo বাকি সব gérer করে });
Entrer en mode plein écran Quitter le mode plein écran

Echo আসলে ভেতরে ভেতরে Connexion WebSocket তৈরি করে, abonnement à la chaîne করে, événement শোনে — তুমি শুধু.écouter()লিখলেই হয়।

4️⃣ Chaîne কত প্রকার ও কী কী?

Voici ce qui suit :

Chaîne হলো Chaîne de télévision-এর মতো। কিছু chaîne সবাই দেখতে পারে, কিছু chaîne শুধু abonné রা।

Chaîne publique → যে কেউ দেখতে পারে (খোলা মাঠের মতো) Chaîne privée → শুধু utilisateur connecté Présence Channel → কে কে en ligne আছে Javascript// Public — যে কেউ Echo.channel('admin-orders') .listen('OrderCreated', (e) => { }); // Privé — Utilisateur authentifié Echo.private('chat.1') // chat.{conversation_id} .listen('MessageSent', (e) => { }); // Privé — নিজের commandes et Echo.private('orders.5') // commandes.{user_id} .listen('OrderStatusUpdated', (e) => { }); php//channels.php — Vérification des autorisations du canal privé Broadcast::channel('chat.{userId}', function ($user, $userId) { // L'utilisateur est-il sur le canal ? return (int) $user->id === (int) $userId; // true দেখতে পাবে, false হলে পাবে না });
Entrer en mode plein écran Quitter le mode plein écran

5️⃣ L'interface de diffusion devrait-elle être utile ? Voici ce qui suit :DevraitDiffuserহলো একটা চিহ্নের মতো 🏷️ যেটা Laravel-কে বলে — "এই Event টা Si PHP est un navigateur Web, WebSocket est un navigateur Web!"

php // ShouldBroadcast ছাড়া: class OrderStatusUpdated // শুধু PHP জানবে, navigateur জানবে না { // ... } // ShouldBroadcast দিয়ে: class OrderStatusUpdated implémente ShouldBroadcast // navigateur-জানবে ! { // ... }php?php namespace App\Events; use App\Models\Orderdetail; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; // ← এই interface use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\InteractsWithSockets; class OrderStatusUpdated implements ShouldBroadcast { use Dispatchable; // broadcast() helper use করতে দেয় use InteractsWithSockets; // WebSocket এর সাথে কাজ করতে দেয় use SerializesModels; // Model কে Queue এ safe রাখে public Orderdetail $order; // ← public মানে broadcast হবে public function __construct(Orderdetail $order) { $this-commande = $commande ; // commande de sauvegarde } public function broadcastOn(): array { // canal এ পাঠাবো? return [ new PrivateChannel('orders.' . $this->order->user_id) ]; } public function BroadcastWith(): array { // contient des données ? return [ 'order_id' => $this->order->id, 'status' => $this->order->status, ]; } }
Entrer en mode plein écran Quitter le mode plein écran

6️⃣diffuser()contreévénement()— Alors?

Voici ce qui suit :

event() → শুধু PHP এর ভেতরে কাজ করে (চিৎকার করো, শুধু ঘরের লোক শুনবে) Broadcast() → PHP + WebSocket দিয়ে navigateur-এও যায় (মাইকে বলো, সবাই শুনবে)

php // Les écouteurs PHP notifient করবে: event(new OrderStatusUpdated($order)); // PHP + Navigateur দুটোই notifier করবে: Broadcast(new OrderStatusUpdated($order)); // Le navigateur notifie করবে কিন্তু যে request করেছে তাকে বাদ দিবে : diffusion (nouveau OrderStatusUpdated($order))->toAutres(); // (écran নিজের এ dupliquer দেখা বন্ধ করতে)
Entrer en mode plein écran Quitter le mode plein écran

7️⃣Sérialise les modèlesTrait কী করে? Bug কেন হয়েছিল?

Voici ce qui suit :

File d'attente হলো একটা লাইনের মতো 🚶‍♂️🚶‍♂️🚶‍♂️ — কাজগুলো একের পর এক হয়।

Sérialise les modèlesQueue-এ Model save করার সময় পুরো Model না রেখে শুধু **ID** রাখে। Il s'agit de l'ID de la base de données et de la base de données.

Problème de bug :

ordre public ; // ← Tapez নেই! __construct($order) // ← Tapez নেই ! File d'attente গেলো: {id: 5} // শুধু ID save হলো Queue থেকে আসলো: ModelIdentifier{id: 5} // Model না, শুধু identifiant objet! $this->order->user_id // ❌ ERREUR ! user_id নেই এই objet এ
Entrer en mode plein écran Quitter le mode plein écran

Réparer:

public Orderdetail $commande ; // ← Tapez দিলাম ! __construct(Orderdetail $order) // ← Tapez দিলাম ! File d'attente গেলো : {id : 5, classe : Orderdetail} File d'attente থেকে আসলো : Orderdetail{id:5, user_id:3, status:'Pending'} // ✅ পুরো Model ! $this->order->user_id // ✅ কাজ করছে !
Entrer en mode plein écran Quitter le mode plein écran

8️⃣ File d'attente কেন দরকার? Diffusion সরাসরি করলে কী হয়? সহজ উত্তর: কল্পনা করো তোমার দোকানে ১০০ জন কাস্টমার একসাথে এলো। File d'attente : তুমি একা সবাইকে একসাথে serve করতে গেলে — সব Très bien! 😵 File d'attente দিয়ে : একটা লাইন তৈরি হবে, একে একে serve হবে — lisse ! ✅

php // Queue ছাড়া Broadcast (synchronous): // Demande de l'utilisateur করলো → Broadcast হলো → তারপর Réponse গেলো // যদি Broadcast lente হয় → utilisateur Bien sûr! // File d'attente দিয়ে diffusion (asynchrone) : // Demande de l'utilisateur করলো → réponse গেলো (rapide !) → arrière-plan এ diffusion হলো classe OrderStatusUpdated implémente ShouldBroadcast { // ShouldBroadcast utilise automatiquement la file d'attente // .env এ QUEUE_CONNECTION=redis dans la file d'attente Redis dans }
Entrer en mode plein écran Quitter le mode plein écran
bash # Queue Worker চালাতে হবে (arrière-plan এ কাজ করে) php artisan queue:work redis # VPS এ Superviseur দিয়ে সবসময় চালু রাখো
Entrer en mode plein écran Quitter le mode plein écran

9️⃣ Canal privé এ Authentification কীভাবে কাজ করে?

Voici ce qui suit :

Chaîne privée হলো তালা দেওয়া ঘরের মতো 🔒। ঢুকতে হলে চাবি লাগবে।

Navigateur utilisateur এ Echo.private('chat.5') লিখলো ↓ Echo automatiquement POST /broadcasting/auth করলো ↓ Vérification Laravel করলো — এই utilisateur কি chat.5 canal এ Qu'est-ce que c'est? ↓channels.php এর callback চললো ↓ true → ঢুকতে পারবে ✅ | faux → ঢুকতে পারবে না ❌
Entrer en mode plein écran Quitter le mode plein écran
php // routes/channels.php Broadcast::channel('chat.{userId}', function ($user, $userId) { // $user = utilisateur actuellement connecté // $userId = nom du canal et {userId} partie // admin et canal দেখতে পারবে // utilisateur Cela signifie que return $user->role === 'admin' || (int) $user->id === (int) $userId }); php // bootstrap/app.php এ activation de la route d'authentification de diffusion করতে হবে ->withRouting(channels: __DIR__.'/../routes/channels.php', // ← এটা থাকতে হবে )
Entrer en mode plein écran Quitter le mode plein écran

🔟diffusionOn()contrediffuserAvec()contrediffusionAs()— Alors?

Voici ce qui suit :

BroadcastOn() → কোথায় পাঠাবো? (Channel এর নাম) BroadcastWith() → কী পাঠাবো? (Data) BroadcastAs() → Est-ce que c'est ça ? (Événement নাম) phpclass MessageSent implémente ShouldBroadcast { public function BroadcastOn(): array { // 📍 কোথায় পাঠাবো? return [new PrivateChannel('chat.' . $this->message->conversation_id)]; } public function BroadcastWith(): array { // 📦 কী data পাঠাবো? return [ 'id' => $this->message->id, 'message' => $this->message->message, 'sender_id' => $this->message->sender_id, 'time' => $this->message->created_at->format('h:i A'), ]; // শুধু দরকারি data পাঠাও — পুরো Modèle না // কারণ পুরো Modèle পাঠালে données sensibles যেতে পারে } public function BroadcastAs(): string { // 🏷️ কী নামে পাঠাবো? renvoyer « MessageEnvoyé » ; // frontend .listen('MessageSent') দিয়ে শুনবো } }
Entrer en mode plein écran Quitter le mode plein écran

1️⃣1️⃣.versAutres()Et maintenant? Qu'est-ce que c'est? সহজ উত্তর : তুমি Message WhatsApp পাঠালে — তোমার নিজের message à l'écran Et toi? Eh bien! শুধু অন্যজনের কাছে যায়।.versAutres()ঠিক সেটাই করে।

php // toAutres() valeur: Broadcast(new MessageSent($message)); // সবাই পাবে — message পাঠানো utilisateur নিজেও পাবে // ফলে message দুইবার Eh bien! (par JS appendMessage par exemple, par Echo par exemple) // toOthers() par exemple: Broadcast(new MessageSent($message))->toOthers(); // message পাঠানো utilisateur বাদে বাকি সবাই পাবে ✅ javascript // Frontend এ নিজের message নিজে append করো: axios.post('/send', {message: msg}) .then(res => { appendMessage(res.data, true); // নিজে append করলাম }); // Echo থেকে শুধু অন্যজনের message: Echo.private('chat.1') .listen('MessageSent', (e) => { // toAutres() থাকায় নিজের message et appendMessage(e.message, false });
Entrer en mode plein écran Quitter le mode plein écran

1️⃣2️⃣ Redis Queue est-ce que tu veux?

Voici ce qui suit :

Redis Queue et la liste des tâches à effectuer 📝

কাজ আসলো → Liste এ লিখলো → Travailleur এসে পড়লো → কাজ করলো → Liste থেকে Voir l...
[Courte citation de 8% de l'article original]
Loading...