DEV Community

Ruhul Amin Sujon
Ruhul Amin Sujon

Posted on

Laravel Reverb & Echo — Interview Q&A

1️⃣ WebSocket কী? HTTP থেকে কীভাবে আলাদা?

সহজ উত্তর:

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

তুমি → চিঠি পাঠালে → বন্ধু পড়লো → জবাব দিলো → শেষ
(প্রতিবার নতুন চিঠি = নতুন connection)
Enter fullscreen mode Exit fullscreen mode

WebSocket হলো ফোন কলের মতো:

তুমি → ফোন করলে → লাইন খোলা রইলো → যেকোনো সময় কথা বলো
(একবার connect = সবসময় connected)
Enter fullscreen mode Exit fullscreen mode

HTTP:

Browser  →→→ Request →→→  Server
Browser  ←←← Response ←←← Server
(connection বন্ধ!)
Enter fullscreen mode Exit fullscreen mode

WebSocket:

Browser  ←——————————————→  Server
         (সবসময় open থাকে)
         যেকোনো সময় data
         দুইদিক থেকেই যেতে পারে
Enter fullscreen mode Exit fullscreen mode

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

তোমার App → Pusher এর Server (বাইরে) → User
            (মাসে টাকা লাগে 💰)
Enter fullscreen mode Exit fullscreen mode

Reverb:

তোমার App → তোমার নিজের Server → User
            (একদম ফ্রি! 🎉)
Enter fullscreen mode Exit fullscreen mode
# Reverb install করা
composer require laravel/reverb
php artisan reverb:install

# চালানো
php artisan reverb:start
Enter fullscreen mode Exit fullscreen mode

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

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 বাকি সব handle করে
    });
Enter fullscreen mode Exit fullscreen mode

Echo আসলে ভেতরে ভেতরে WebSocket connection তৈরি করে, channel subscribe করে, event শোনে — তুমি শুধু .listen() লিখলেই হয়।


4️⃣ Channel কত প্রকার ও কী কী?

সহজ উত্তর:

Channel হলো TV channel-এর মতো। কিছু channel সবাই দেখতে পারে, কিছু channel শুধু subscriber রা।

Public Channel  → যে কেউ দেখতে পারে (খোলা মাঠের মতো)
Private Channel → শুধু logged-in user দেখতে পারে (বাড়ির ভেতরের মতো)
Presence Channel → কে কে online আছে সেটাও জানা যায় (হাজিরা খাতার মতো)
javascript// Public — যে কেউ
Echo.channel('admin-orders')
    .listen('OrderCreated', (e) => { });

// Private — শুধু authenticated user
Echo.private('chat.1')        // chat.{conversation_id}
    .listen('MessageSent', (e) => { });

// Private — শুধু নিজের orders দেখবে
Echo.private('orders.5')      // orders.{user_id}
    .listen('OrderStatusUpdated', (e) => { });
php// channels.php — Private channel এর permission check
Broadcast::channel('chat.{userId}', function ($user, $userId) {
    // এই user কি এই channel দেখার অনুমতি রাখে?
    return (int) $user->id === (int) $userId;
    // true হলে দেখতে পাবে, false হলে পাবে না
});
Enter fullscreen mode Exit fullscreen mode

5️⃣ ShouldBroadcast Interface কী করে?
সহজ উত্তর:
ShouldBroadcast হলো একটা চিহ্নের মতো 🏷️ যেটা Laravel-কে বলে — "এই Event টা শুধু PHP-তে রাখো না, WebSocket দিয়ে browser-এও পাঠাও!"

php
// ShouldBroadcast ছাড়া:
class OrderStatusUpdated  // শুধু PHP জানবে, browser জানবে না
{
    // ...
}

// ShouldBroadcast দিয়ে:
class OrderStatusUpdated implements ShouldBroadcast  // browser-ও জানবে!
{
    // ...
}
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->order = $order; // order save করো
    }

    public function broadcastOn(): array
    {
        // কোন channel এ পাঠাবো?
        return [
            new PrivateChannel('orders.' . $this->order->user_id)
        ];
    }

    public function broadcastWith(): array
    {
        // কী data পাঠাবো?
        return [
            'order_id' => $this->order->id,
            'status'   => $this->order->status,
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

6️⃣ broadcast() vs event()পার্থক্য কী?

সহজ উত্তর:

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

php
// শুধু PHP listeners notify করবে:
event(new OrderStatusUpdated($order));

// PHP + Browser দুটোই notify করবে:
broadcast(new OrderStatusUpdated($order));

// Browser notify করবে কিন্তু যে request করেছে তাকে বাদ দিবে:
broadcast(new OrderStatusUpdated($order))->toOthers();
// (নিজের screen এ duplicate দেখা বন্ধ করতে)
Enter fullscreen mode Exit fullscreen mode

7️⃣ SerializesModels Trait কী করে? Bug কেন হয়েছিল?

সহজ উত্তর:

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

SerializesModels Queue-এ Model save করার সময় পুরো Model না রেখে শুধু **ID** রাখে। পরে কাজ করার সময় সেই ID দিয়ে DB থেকে আবার আনে।

Bug হওয়ার কারণ:

public $order;              // ← Type নেই!
__construct($order)         // ← Type নেই!

Queue এ গেলো: {id: 5}     // শুধু ID save হলো
Queue থেকে আসলো: ModelIdentifier{id: 5}  // Model না, শুধু identifier object!
$this->order->user_id      // ❌ ERROR! user_id নেই এই object এ

Enter fullscreen mode Exit fullscreen mode

Fix:

public Orderdetail $order;           // ← Type দিলাম!
__construct(Orderdetail $order)      // ← Type দিলাম!

Queue এ গেলো: {id: 5, class: Orderdetail}
Queue থেকে আসলো: Orderdetail{id:5, user_id:3, status:'Pending'}  // ✅ পুরো Model!
$this->order->user_id      // ✅ কাজ করছে!
Enter fullscreen mode Exit fullscreen mode

8️⃣ Queue কেন দরকার? Broadcast সরাসরি করলে কী হয়?
সহজ উত্তর:
কল্পনা করো তোমার দোকানে ১০০ জন কাস্টমার একসাথে এলো।
Queue ছাড়া: তুমি একা সবাইকে একসাথে serve করতে গেলে — সব ভেঙে পড়বে! 😵
Queue দিয়ে: একটা লাইন তৈরি হবে, একে একে serve হবে — smooth! ✅

php
// Queue ছাড়া broadcast (synchronous):
// User request করলো → broadcast হলো → তারপর response গেলো
// যদি broadcast slow হয় → user অপেক্ষা করবে!

// Queue দিয়ে broadcast (asynchronous):
// User request করলো → response গেলো (fast!) → background এ broadcast হলো
class OrderStatusUpdated implements ShouldBroadcast
{
    // ShouldBroadcast automatically queue use করে
    // .env এ QUEUE_CONNECTION=redis থাকলে Redis queue এ যাবে
}
Enter fullscreen mode Exit fullscreen mode
bash
# Queue worker চালাতে হবে (background এ কাজ করে)
php artisan queue:work redis

# VPS এ Supervisor দিয়ে সবসময় চালু রাখো
Enter fullscreen mode Exit fullscreen mode

9️⃣ Private Channel এ Authentication কীভাবে কাজ করে?

সহজ উত্তর:

Private channel হলো তালা দেওয়া ঘরের মতো 🔒। ঢুকতে হলে চাবি লাগবে।

User browser এ Echo.private('chat.5') লিখলো
        ↓
Echo automatically POST /broadcasting/auth করলো
        ↓
Laravel check করলো — এই user কি chat.5 channel এ ঢুকতে পারবে?
        ↓
channels.php এর callback চললো
        ↓
true → ঢুকতে পারবে ✅  |  false → ঢুকতে পারবে না ❌
Enter fullscreen mode Exit fullscreen mode
php
// routes/channels.php
Broadcast::channel('chat.{userId}', function ($user, $userId) {
    // $user = currently logged in user
    // $userId = channel name এর {userId} part

    // admin সব channel দেখতে পারবে
    // user শুধু নিজেরটা দেখতে পারবে
    return $user->role === 'admin' || (int) $user->id === (int) $userId;
});
php
// bootstrap/app.php এ broadcasting auth route enable করতে হবে
->withRouting(
    channels: __DIR__.'/../routes/channels.php', // ← এটা থাকতে হবে
)
Enter fullscreen mode Exit fullscreen mode

🔟 broadcastOn() vs broadcastWith() vs broadcastAs()পার্থক্য কী?

সহজ উত্তর:

broadcastOn()   → কোথায় পাঠাবো? (Channel এর নাম)
broadcastWith() → কী পাঠাবো? (Data)
broadcastAs()   → কী নামে পাঠাবো? (Event এর নাম)
phpclass MessageSent implements 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 পাঠাও — পুরো Model না
        // কারণ পুরো Model পাঠালে sensitive data যেতে পারে
    }

    public function broadcastAs(): string
    {
        // 🏷️ কী নামে পাঠাবো?
        return 'MessageSent';
        // frontend এ .listen('MessageSent') দিয়ে শুনবো
    }
}
Enter fullscreen mode Exit fullscreen mode

1️⃣1️⃣ .toOthers() কী করে? কখন দরকার?
সহজ উত্তর:
তুমি WhatsApp-এ message পাঠালে — তোমার নিজের screen-এ কি message আবার আসে? না! শুধু অন্যজনের কাছে যায়।
.toOthers() ঠিক সেটাই করে।

php
// toOthers() ছাড়া:
broadcast(new MessageSent($message));
// সবাই পাবে — message পাঠানো user নিজেও পাবে
// ফলে message দুইবার দেখাবে! (একবার JS appendMessage থেকে, একবার Echo থেকে)

// toOthers() দিয়ে:
broadcast(new MessageSent($message))->toOthers();
// message পাঠানো user বাদে বাকি সবাই পাবে ✅
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) => {
        // toOthers() থাকায় নিজের message এখানে আসবে না
        appendMessage(e.message, false);
    });
Enter fullscreen mode Exit fullscreen mode

1️⃣2️⃣ Redis Queue কীভাবে কাজ করে?

সহজ উত্তর:

Redis Queue হলো একটা To-Do List এর মতো 📝

কাজ আসলো → List এ লিখলো → Worker এসে পড়লো → কাজ করলো → List থেকে কাটলো

broadcast() call হলো
        ↓
Redis এ job save হলো (list এ ঢুকলো)
        ↓
queue:work worker সেটা দেখলো
        ↓
WebSocket এ data পাঠালো
        ↓
Job শেষ (list থেকে কাটলো) ✅
Enter fullscreen mode Exit fullscreen mode
bash
# Redis এ কী আছে দেখো
redis-cli
> KEYS *           # সব keys দেখো
> LLEN queues:default  # queue তে কতটা job আছে
env# .env
QUEUE_CONNECTION=redis   # ← Redis use করবে
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
Enter fullscreen mode Exit fullscreen mode

1️⃣3️⃣ Ajax দুইবার call হওয়ার কারণ কী ছিল?
সহজ উত্তর:
কল্পনা করো তুমি doorbell বাজালে — কিন্তু doorbell এ দুটো বোতাম আছে, দুটোই same কাজ করে। তুমি একটা বাজালেও দুইটাই বাজলো!

javascript
// সমস্যা ছিল:
// ১. Form এর submit event
// ২. Button এর type="submit" — এটাও form submit করে
// = দুইবার submit!

// আরেকটা কারণ:
// @push('scripts') যদি দুইবার load হয়
// তাহলে addEventListener দুইবার attach হয়
// = দুইবার call!
javascript
// Fix:
const form = document.getElementById('chat-form');

// পুরনো সব listener মুছে ফেলো (clone করে)
const freshForm = form.cloneNode(true);
form.parentNode.replaceChild(freshForm, form);

freshForm.addEventListener('submit', function(e) {
    e.preventDefault();      // form submit বন্ধ করো
    e.stopPropagation();     // event bubble বন্ধ করো

    if (sending) return;     // already sending হলে আর করো না
    sending = true;          // flag set করো

    // ... axios call
});
Enter fullscreen mode Exit fullscreen mode

1️⃣4️⃣ Supervisor কী? VPS-এ কেন দরকার?

সহজ উত্তর:

Supervisor হলো একজন Manager এর মতো 👨‍💼

তুমি যদি php artisan queue:work manually চালাও — CMD বন্ধ করলেই সব বন্ধ। কিন্তু Manager (Supervisor) সবসময় দেখছে — কিছু বন্ধ হলে আবার চালু করে দেয়।

তুমি ঘুমাও 😴
        ↓
queue:work crash করলো!
        ↓
Supervisor দেখলো — "আরে বন্ধ হয়ে গেছে!"
        ↓
Supervisor আবার চালু করলো ✅
        ↓
তুমি জানোও না কিছু হয়েছিল
Enter fullscreen mode Exit fullscreen mode
ini; 
/etc/supervisor/conf.d/reverb.conf
[program:reverb]
command=php /var/www/project/artisan reverb:start
autostart=true    ; server start হলে automatically চালু হবে
autorestart=true  ; crash করলে automatically restart হবে
user=www-data

; /etc/supervisor/conf.d/queue.conf
[program:queue]
command=php /var/www/project/artisan queue:work redis
autostart=true
autorestart=true
numprocs=2        ; দুটো worker একসাথে চলবে
user=www-data
Enter fullscreen mode Exit fullscreen mode

1️⃣5️⃣ ShouldBroadcastNow vs ShouldBroadcastপার্থক্য কী?

সহজ উত্তর:

ShouldBroadcast     → Queue এ যাবে, একটু পরে পাঠাবে (ডাকযোগে চিঠি)
ShouldBroadcastNow  → Queue bypass করে এখনই পাঠাবে (হাতে হাতে চিঠি)
Enter fullscreen mode Exit fullscreen mode
php
// Queue এ যাবে (recommended for production):
class MessageSent implements ShouldBroadcast { }

// এখনই যাবে, Queue bypass (development/testing এ ভালো):
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
class MessageSent implements ShouldBroadcastNow { }
Enter fullscreen mode Exit fullscreen mode

কখন কোনটা?

ShouldBroadcast:
✅ Production এ (VPS)
✅ অনেক user থাকলে
✅ Server load কমাতে

ShouldBroadcastNow:
✅ Development এ test করতে
✅ queue:work চালু না থাকলে
✅ Critical notification (এখনই দরকার)


1️⃣6️⃣ Unread Message Count কীভাবে কাজ করে?

সহজ উত্তর:

এটা হলো তোমার WhatsApp-এর লাল badge এর মতো 🔴

নতুন message আসলো
        ↓
Echo .listen() এ ধরা পড়লো
        ↓
JavaScript counter++ করলো
        ↓
Badge এ number দেখালো
        ↓
User click করলো → counter = 0 → badge লুকালো
Enter fullscreen mode Exit fullscreen mode
javascript

let unreadCount = 0;

Echo.private('chat.' + conversationId)
    .listen('MessageSent', (e) => {

        // নিজের message হলে ignore করো
        if (e.message.sender_id === {{ auth()->id() }}) return;

        // Message দেখাও
        appendMessage(e.message, false);

        // Sound বাজাও
        document.getElementById('chatSound').play();

        // Count বাড়াও
        unreadCount++;
        let badge = document.getElementById('unread-badge');
        badge.innerText = unreadCount;
        badge.classList.remove('d-none'); // দেখাও
    });

// User chat খুললে reset করো
function resetUnreadCount() {
    unreadCount = 0;
    document.getElementById('unread-badge').classList.add('d-none'); // লুকাও
}
Enter fullscreen mode Exit fullscreen mode
php
// DB তেও unread count রাখো (page refresh এর পরেও থাকবে)
// messages table এ is_read column
Message::where('conversation_id', $id)
       ->where('sender_id', '!=', auth()->id())
       ->where('is_read', false)
       ->update(['is_read' => true]);
Enter fullscreen mode Exit fullscreen mode

1️⃣7️⃣ .env এ Reverb Config কী মানে?
সহজ উত্তর:

env
# Reverb কোন address এ চলবে?
REVERB_HOST=0.0.0.0      # সব network থেকে connection নেবে
                          # (127.0.0.1 হলে শুধু local থেকে নিতো)

REVERB_PORT=8080          # কোন port এ শুনবে?
                          # (80 হলো HTTP, 443 হলো HTTPS, 8080 হলো custom)

REVERB_SCHEME=https       # http নাকি https?
                          # Production এ সবসময় https

# Frontend (JavaScript) কোথায় connect করবে?
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"   # চাবি — match করতে হবে
VITE_REVERB_HOST="${APP_URL}"             # কোথায় connect করবে
VITE_REVERB_PORT="${REVERB_PORT}"         # কোন port এ
VITE_REVERB_SCHEME="${REVERB_SCHEME}"     # http/https
Enter fullscreen mode Exit fullscreen mode
javascript
// bootstrap.js এ এই config use হয়:
window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,    // .env থেকে আসে
    wsHost: import.meta.env.VITE_REVERB_HOST,    // .env থেকে আসে
    wsPort: import.meta.env.VITE_REVERB_PORT,    // .env থেকে আসে
    forceTLS: true,  // https use করবে
});
Enter fullscreen mode Exit fullscreen mode

1️⃣8️⃣ Nginx দিয়ে Reverb Proxy কেন দরকার?

সহজ উত্তর:

তোমার বাড়িতে একটাই দরজা (port 443/HTTPS)। কিন্তু ভেতরে দুটো ঘর আছে — একটা website (Laravel), একটা WebSocket (Reverb)।

Nginx হলো দারোয়ানের মতো 💂 — কে কোন ঘরে যাবে সেটা দেখে।

User এর browser
        ↓
https://yourdomain.com (port 443)
        ↓
    Nginx (দারোয়ান)
    /        → Laravel (website)
    /app      → Reverb (WebSocket)
Enter fullscreen mode Exit fullscreen mode
nginx
# Normal website traffic → Laravel
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

# WebSocket traffic → Reverb
location /app {
    proxy_pass http://127.0.0.1:8080;  # Reverb এ পাঠাও
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;      # WebSocket upgrade
    proxy_set_header Connection "Upgrade";       # WebSocket upgrade
}
Enter fullscreen mode Exit fullscreen mode

1️⃣9️⃣ Real-time Order Status কীভাবে কাজ করে — পুরো flow?

সহজ উত্তর:

Admin order status change করলো
            ↓
OrderController → orderStatusUpdate()
            ↓
DB তে status save হলো
            ↓
broadcast(new OrderStatusUpdated($order))
            ↓
Redis Queue তে job গেলো
            ↓
queue:work worker job নিলো
            ↓
Reverb WebSocket server এ পাঠালো
            ↓
User এর browser Echo.private('orders.5') শুনছিলো
            ↓
.listen('OrderStatusUpdated') এ ধরা পড়লো
            ↓
JavaScript DOM update করলো (page refresh ছাড়া!) ✅
Enter fullscreen mode Exit fullscreen mode
javascript
// User এর order page এ:
Echo.private('orders.{{ auth()->id() }}')
    .listen('.OrderStatusUpdated', (e) => {

        // Status badge update করো
        let badge = document.querySelector('#order-' + e.order_id + ' .status-badge');
        if (badge) {
            badge.textContent = e.status;
            // পুরনো class সরাও, নতুন class দাও
            badge.className = 'badge status-' + e.status.toLowerCase();
        }

        // Toast notification দেখাও
        alert('তোমার অর্ডার আপডেট হয়েছে: ' + e.status);
    });
Enter fullscreen mode Exit fullscreen mode

2️⃣0️⃣ Production এ কী কী Check করতে হবে?
সহজ উত্তর:
বাড়ি বানানো শেষ — এখন চেক করো সব ঠিক আছে কিনা 🏠

bash
# ১. Reverb চলছে কিনা দেখো
sudo supervisorctl status glamours-reverb
# RUNNING দেখালে ✅

# ২. Queue worker চলছে কিনা দেখো
sudo supervisorctl status glamours-queue
# RUNNING দেখালে ✅

# ৩. Redis চলছে কিনা দেখো
redis-cli ping
# PONG দেখালে ✅

# ৪. WebSocket connection test করো
# Browser Console এ:
# Echo.connector.pusher.connection.state
# "connected" দেখালে ✅

# ৫. Laravel Config cache করো
php artisan config:cache
php artisan route:cache
php artisan event:cache

# ৬. Failed jobs আছে কিনা দেখো
php artisan queue:failed
# কিছু না দেখালে ✅

# ৭. Log দেখো
tail -f storage/logs/laravel.log
# Error না দেখালে ✅
Enter fullscreen mode Exit fullscreen mode
Production Checklist:
[ ] APP_DEBUG=false
[ ] APP_ENV=production
[ ] QUEUE_CONNECTION=redis
[ ] BROADCAST_CONNECTION=reverb
[ ] Supervisor running (reverb + queue)
[ ] SSL certificate valid (https)
[ ] Nginx proxy configured
[ ] Redis running
[ ] Storage link created
[ ] Config cached
Enter fullscreen mode Exit fullscreen mode

🎯 Quick Summary — একনজরে

WebSocket    = সবসময় open ফোন লাইন
Reverb       = নিজের WebSocket server (ফ্রি!)
Echo         = Browser এ WebSocket শোনার কান
Channel      = TV channel (Public/Private)
ShouldBroadcast = "Browser কেও জানাও" চিহ্ন
broadcast()  = সবাইকে বলো
toOthers()   = নিজে বাদে সবাইকে বলো
Queue        = কাজের লাইন (background এ)
Redis        = দ্রুত Queue storage
Supervisor   = সবসময় চালু রাখার Manager
SerializesModels = Queue এ Model safe রাখে (Type hint দিতে হবে!)
Enter fullscreen mode Exit fullscreen mode

Q_21: which network use Reverb? https network vs Reverb network? explain like as i am 6 years oldMar 6HTTPS vs Reverb Network

Answer:

🏠 একটা গল্প দিয়ে শুরু করি
কল্পনা করো তোমার বাড়িতে দুই ধরনের যোগাযোগ আছে:

১. 📬 চিঠির বাক্স (HTTPS)
   → তুমি চিঠি পাঠাও
   → জবাব আসে
   → তারপর শেষ

২. 📞 টেলিফোন (WebSocket/Reverb)
   → একবার কল করো
   → লাইন সবসময় খোলা থাকে
   → যেকোনো সময় কথা বলো
Enter fullscreen mode Exit fullscreen mode

🌐 HTTPS কীভাবে কাজ করে?

তুমি Browser এ click করলে
         ↓
Browser → "এই page টা দাও" → Server
         ↓
Server → "এই নাও page" → Browser
         ↓
    Connection বন্ধ! 🔒
    (কাজ শেষ, বিদায়!)
Enter fullscreen mode Exit fullscreen mode

Real Example:

তুমি → glamoursworld.com/products চাইলে
         ↓
HTTPS Request গেলো Port 443 দিয়ে
         ↓
Server HTML পাঠালো
         ↓
Connection বন্ধ হয়ে গেলো

পরের বার products এ কিছু add হলে?
তুমি জানবে না! কারণ connection নেই! 😢
তোমাকে আবার refresh করতে হবে।
Enter fullscreen mode Exit fullscreen mode

WebSocket (Reverb) কীভাবে কাজ করে?

তুমি Browser খুললে
         ↓
Browser → "আমি সবসময় connected থাকতে চাই" → Reverb Server
         ↓
Reverb → "ঠিক আছে, লাইন খোলা রাখলাম" → Browser
         ↓
    Connection সবসময় খোলা! 📞
         ↓
যেকোনো সময় Server → Browser তে data পাঠাতে পারে!
যেকোনো সময় Browser → Server তে data পাঠাতে পারে!
Enter fullscreen mode Exit fullscreen mode

Real Example:

Admin order status "Shipped" করলো
         ↓
Reverb এর লাইন দিয়ে এখনই গেলো
         ↓
তোমার browser এ pop up দেখালো
         ↓
তুমি refresh করোনি, কিন্তু দেখলে! 🎉
Enter fullscreen mode Exit fullscreen mode

🔌 কোন Port দিয়ে কোনটা চলে?

HTTPS  → Port 443  (সব normal website traffic)
HTTP   → Port 80   (insecure, redirect হয় 443 এ)
Reverb → Port 8080 (WebSocket traffic)
Enter fullscreen mode Exit fullscreen mode

কিন্তু তোমার user দুটো port মনে রাখবে কীভাবে?
রাখতে হবে না! Nginx দারোয়ান সব handle করে:

glamoursworld.com      → Port 443 → Nginx → Laravel (Port 9000)
glamoursworld.com/app  → Port 443 → Nginx → Reverb  (Port 8080)

User শুধু glamoursworld.com জানলেই হলো!
Nginx বাকি সব করে। ✅
Enter fullscreen mode Exit fullscreen mode

🔍 Network Tab এ দেখলে কেমন দেখায়?
Browser এ F12 চাপো → Network tab → দেখবে:

HTTPS Requests (সাদা background):
GET  /products          200 OK   (page load)
POST /order-status      200 OK   (form submit)
GET  /api/messages      200 OK   (ajax call)
এগুলো আসে যায়, connection বন্ধ হয়।

WebSocket (হলুদ/নীল background):
WS   /app?appKey=xxx    101 Switching Protocols
↑
এটা একবার connect হয়, তারপর সবসময় open থাকে!
101 মানে "ঠিক আছে, HTTP থেকে WebSocket এ upgrade হলাম"
Enter fullscreen mode Exit fullscreen mode

🏗️ তোমার Project এ কোনটা কীসের জন্য?
┌─────────────────────────────────────────────────────┐
│ glamoursworld.com │
├─────────────────────┬───────────────────────────────┤
│ HTTPS (Port 443) │ WebSocket/Reverb (Port 8080) │
├─────────────────────┼───────────────────────────────┤
│ Page load করা │ Real-time chat message │
│ Form submit করা │ Order status update │
│ Image upload করা │ New order notification │
│ Login/Logout │ Unread message count │
│ Product দেখা │ Sound notification │
│ Order place করা │ Admin badge count │
└─────────────────────┴───────────────────────────────┘

📡 Protocol পরিবর্তন কীভাবে হয়?
শুরুতে HTTPS দিয়ে হাত মেলানো হয়:

Browser: "নমস্কার! আমি WebSocket connection চাই"
         GET /app HTTP/1.1
         Upgrade: websocket          ← "upgrade করতে চাই"
         Connection: Upgrade
         Sec-WebSocket-Key: abc123   ← "এই চাবি দিয়ে চিনবো"

Reverb:  "ঠিক আছে! চলো upgrade করি"
         HTTP/1.1 101 Switching Protocols  ← "101 = রাজি!"
         Upgrade: websocket
         Connection: Upgrade

এরপর থেকে:
Browser ←————— WebSocket ——————→ Reverb
        (আর HTTP না, এখন WS protocol)
Enter fullscreen mode Exit fullscreen mode

🔒 WSS vs WS — কোনটা ব্যবহার করবে?

WS  = ws://  = WebSocket (insecure, HTTP এর মতো)
WSS = wss:// = WebSocket Secure (secure, HTTPS এর মতো)

ঠিক যেমন:
HTTP  → HTTPS (তালা দেওয়া)
WS    → WSS   (তালা দেওয়া)
Enter fullscreen mode Exit fullscreen mode

Production VPS এ সবসময় WSS ব্যবহার করো:

.env:
REVERB_SCHEME=https   ← এটা দিলে WSS automatically use হবে

bootstrap.js:
window.Echo = new Echo({
    forceTLS: true,   ← WSS force করো (wss://)
});
Enter fullscreen mode Exit fullscreen mode

🎯 এক লাইনে Summary

HTTPS  = চিঠি  📬 (পাঠাও, জবাব পাও, শেষ)
Reverb = ফোন   📞 (একবার connect, সবসময় কথা বলো)

দুটো একসাথে চলে, দুটো আলাদা কাজ করে।
তোমার project এ দুটোই দরকার! ✅
Enter fullscreen mode Exit fullscreen mode

Q_22: whisper & listenForWhisper কী?
Answer:

🗣️ একটা গল্প দিয়ে শুরু করি
কল্পনা করো তুমি ক্লাসরুমে আছো।

😤 জোরে কথা বলা (broadcast):
"আমি message পাঠালাম!"
→ সবাই শুনলো
→ Teacher ও শুনলো
→ Database এ লেখা হলো
→ সবাই জানলো

🤫 কানে কানে বলা (whisper):
"আমি টাইপ করছি..."
→ শুধু পাশের বন্ধু শুনলো
→ Teacher জানলো না
→ Database এ কিছু লেখা হলো না
→ এক সেকেন্ড পরে ভুলে গেলো
Enter fullscreen mode Exit fullscreen mode

whisper হলো কানে কানে বলার মতো! 🤫


🔍 Code Line by Line বোঝো
Part 1: User টাইপ করলে whisper পাঠাও

javascript
// User যখন message box এ কিছু লিখতে শুরু করে
messageInput.addEventListener('input', () => {
    // ← 'input' মানে keyboard এ যেকোনো key press হলে

    // কানে কানে বলো (whisper) — শুধু ওই channel এর লোক শুনবে
    Echo.private('chat.' + conversationId)
    //   ↑ এই specific conversation এর channel এ
        .whisper('typing', {
        //        ↑ event এর নাম 'typing'
            user_id: {{ auth()->id() }},
            // ↑ আমি কে? (যাতে নিজের typing indicator না দেখাই)
            typing: true
            // ↑ "হ্যাঁ, আমি এখন টাইপ করছি"
        });
Enter fullscreen mode Exit fullscreen mode

Part 2: ১ সেকেন্ড পরে টাইপিং বন্ধ

javascript    
// আগের timer বাতিল করো
    clearTimeout(typingTimer);
    // ↑ কেন? user প্রতিটা key press এ timer reset করবে
    // "a" চাপলো → 1 sec timer শুরু
    // "b" চাপলো → আগের timer বাতিল, নতুন timer শুরু
    // "c" চাপলো → আবার বাতিল, নতুন timer
    // শেষ key press এর ১ সেকেন্ড পরে চলবে ↓

    typingTimer = setTimeout(() => {
    //            ↑ ১ সেকেন্ড পরে এই কাজ করো

        Echo.private('chat.' + conversationId)
            .whisper('typing', {
                user_id: {{ auth()->id() }},
                typing: false
                // ↑ "আমি এখন আর টাইপ করছি না"
            });

    }, 1000);
    //  ↑ 1000 millisecond = 1 second
Enter fullscreen mode Exit fullscreen mode

Part 3: অন্যজনের typing শোনো

javascript
Echo.private('chat.' + conversationId)
    .listenForWhisper('typing', (e) => {
    //                 ↑ 'typing' whisper আসলে এই কাজ করো

        // নিজের typing indicator দেখাবো না!
        if(e.user_id === {{ auth()->id() }}) return;
        //  ↑ যদি আমি নিজেই পাঠিয়ে থাকি → ignore করো

        let indicator = document.getElementById('typing-indicator');
        // ↑ HTML এ এই element টা ধরো (যেখানে "typing..." দেখাবে)

        if(e.typing){
            indicator.style.display = 'block'; // দেখাও ✅
        }else{
            indicator.style.display = 'none';  // লুকাও ✅
        }
    });
Enter fullscreen mode Exit fullscreen mode

🆚 whisper vs broadcastপার্থক্য কী?

                    whisper          broadcast
                    ───────          ─────────
Database save?      ❌ না            ✅ হ্যাঁ
Queue use করে?      ❌ না            ✅ হ্যাঁ
Server এ যায়?       ❌ না*           ✅ হ্যাঁ
শুধু Channel এ?     ✅ হ্যাঁ         ✅ হ্যাঁ
Speed?              ⚡ অনেক দ্রুত   🐢 একটু ধীর
কাজ?               ক্ষণস্থায়ী      স্থায়ী
Enter fullscreen mode Exit fullscreen mode

*whisper সরাসরি Reverb এর মাধ্যমে peer-to-peer যায়, Laravel server এ যায় না!


⚡ কেন whisper ব্যবহার করলাম?

Typing indicator এর জন্য broadcast ব্যবহার করলে কী হতো?

User "Hello" লিখলো = 5 টা key press
         ↓
5 টা broadcast() call
         ↓
5 টা Queue job
         ↓
5 টা Database query (না হলেও server এ যেতো)
         ↓
Server এ অনেক চাপ! 😵
Enter fullscreen mode Exit fullscreen mode
Whisper ব্যবহার করলে:

User "Hello" লিখলো = 5 টা key press
         ↓
5 টা whisper (সরাসরি WebSocket এ)
         ↓
0 টা Queue job
         ↓
0 টা Database query
         ↓
Server এ কোনো চাপ নেই! 😎✅
Enter fullscreen mode Exit fullscreen mode

🎬 Real-life Flow দেখো

Rafi টাইপ করছে → Mim দেখছে

Rafi এর screen:               Mim এর screen:
─────────────                 ──────────────
[Hello world...]              [          ]
     ↓                             ↓
whisper('typing',{true})  →→→ listenForWhisper
     ↓                             ↓
                              "Rafi is typing..." 💬

Rafi ১ সেকেন্ড থামলো:
whisper('typing',{false}) →→→ listenForWhisper
                               typing indicator লুকালো 🙈
Enter fullscreen mode Exit fullscreen mode

🎯 এক লাইনে Summary

**whisper**         = কানে কানে বলা 🤫
                  (database নেই, server নেই, শুধু channel এ)

**listenForWhisper** = কান পেতে শোনা 👂
                  (whisper আসলে সাথে সাথে react করো)

**কেন দরকার?**     = Typing indicator এর মতো
                  ক্ষণস্থায়ী জিনিসের জন্য
                  যেটা save করার দরকার নেই
                  কিন্তু real-time দেখাতে হবে ✅

**_Q_23_**: websocket, পিএইচপি তে কিভাবে চেক করতে পারি? কোন নেটওয়ার্ক ব্যবহার করে? Networking  এর সাথে websocket সম্পর্ক কি?

**Answer**: 

1️⃣ **WebSocket আসলে কী?**

WebSocket হলো একটি **persistent (সবসময় খোলা)** full-duplex communication protocol।

👉 মানে:

- Client ↔ Server **একই connection এ দু’দিকেই data পাঠাতে পারে**
- HTTP এর মতো বারবার request–response লাগে না

উদাহরণ:

- Chat app
- Live notification
- Real-time dashboard
- Facebook feed update

2️⃣ **WebSocket কোন Network / Protocol ব্যবহার করে?**
🔹 **Layer অনুযায়ী দেখি (Networking view)**

Enter fullscreen mode Exit fullscreen mode

Application Layer → WebSocket (ws / wss)
Transport Layer → TCP
Network Layer → IP


👉 **WebSocket = TCP এর উপর তৈরি**
👉 **UDP না**, কারণ reliability দরকার

🔹 **Port ব্যবহার**

![ ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/prj8a5pks8z4pqdbd1sd.png)



👉 `wss://` = WebSocket over TLS (HTTPS-এর মতো secure)

3️⃣ **HTTP vs WebSocket (Networking পার্থক্য)**

![ ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vqq7t7f3toejdgcv0ui.png)



📌 WebSocket **HTTP দিয়ে শুরু হয়**, কিন্তু পরে HTTP না থাকে।

4️⃣ **WebSocket কীভাবে শুরু হয়? (Handshake)**

👉 শুরু হয় HTTP request দিয়ে:

Enter fullscreen mode Exit fullscreen mode

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xyz
Sec-WebSocket-Version: 13


Server reply দেয়:

Enter fullscreen mode Exit fullscreen mode

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade


✔ এরপর connection পুরোপুরি WebSocket হয়ে যায়

---

5️⃣ **PHP তে WebSocket কিভাবে চেক করবো?**
✅ **Method–1: Request Header দেখে (PHP)**

Enter fullscreen mode Exit fullscreen mode

if (
isset($_SERVER['HTTP_UPGRADE']) &&
strtolower($_SERVER['HTTP_UPGRADE']) === 'websocket'
) {
echo "This is a WebSocket request";
}

✅ **Method–2: fsockopen দিয়ে low-level check**

Enter fullscreen mode Exit fullscreen mode

$socket = fsockopen("tcp://127.0.0.1", 6001, $errno, $errstr, 2);

if ($socket) {
echo "WebSocket server is running";
} else {
echo "WebSocket server not reachable";
}

✅ **Method–3: Laravel WebSocket (Recommended)**

যদি Laravel ব্যবহার করো:

Enter fullscreen mode Exit fullscreen mode

php artisan websockets:serve


Browser console:

Enter fullscreen mode Exit fullscreen mode

let ws = new WebSocket("ws://localhost:6001");
ws.onopen = () => console.log("Connected");

6️⃣ **PHP দিয়ে WebSocket Server কিভাবে বানানো হয়?**

👉 Pure PHP দিয়ে সাধারণত Ratchet ব্যবহার করা হয়।

Enter fullscreen mode Exit fullscreen mode

composer require cboden/ratchet


Enter fullscreen mode Exit fullscreen mode

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
public function onMessage(ConnectionInterface $conn, $msg) {
$conn->send("Server got: $msg");
}
}


📌 Laravel এ সাধারণত:

- **Laravel WebSockets**
- **Pusher**
- **Socket.IO (Node.js backend)**

7️⃣ **Networking এর সাথে WebSocket এর সম্পর্ক কী?**

👉 সংক্ষেপে:

Enter fullscreen mode Exit fullscreen mode

বিষয় সম্পর্ক
TCP WebSocket TCP ব্যবহার করে
Port 80 / 443
Firewall HTTPS এর মতো pass করে
Latency কম
Stateful Yes
OSI Layer Application layer




👉 WebSocket হলো **Networking-এর real-time application layer protocol**

8️⃣ **Real-Life Analogy** 🧠

- HTTP = দরজায় নক (প্রতি বার knock)
- WebSocket = ফোন কল (একবার ধরলে কথা চলতেই থাকে)

---

🧠 **Interview-Ready Answer (Short)**

> WebSocket is a full-duplex, persistent protocol built on top of TCP.
> It starts with an HTTP handshake, then upgrades to ws/wss.
> In PHP, WebSocket requests can be detected via Upgrade headers or by running a WebSocket server like Ratchet or Laravel WebSockets.
> It’s tightly related to networking as it operates at the application layer over TCP/IP.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)