Tuesday, 25 February 2025

Building a Scalable & Secure Private Chat with Laravel 11, Reverb, Redis & Vue 3 + TypeScript

This guide walks through creating a production-ready real-time private chat system using:
Laravel 11 (Backend)
Reverb + Redis (Real-time WebSockets)
Vue 3 + TypeScript (Frontend)
Nginx Load Balancer (Multi-server Scaling)


πŸ”Ή Backend: Laravel 11 + Reverb + Redis

1️⃣ Setup Laravel 11 & Dependencies

bash
composer create-project laravel/laravel chat-app cd chat-app composer require predis/predis

2️⃣ Install & Configure Laravel Reverb

bash
php artisan reverb:install php artisan vendor:publish --tag=reverb-config

πŸ”Ή Modify .env

env
BROADCAST_CONNECTION=redis QUEUE_CONNECTION=redis

πŸ”Ή Modify config/broadcasting.php

php
'connections' => [ 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], ],

πŸ”Ή Start Redis

bash
redis-server

πŸ›  Step 2: Database & Models

1️⃣ Create Chat Model & Migration

bash
php artisan make:model Chat -m

Define chats table structure

php
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::create('chats', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('sender_id'); $table->unsignedBigInteger('receiver_id'); $table->text('message'); // Store encrypted messages $table->timestamps(); $table->foreign('sender_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('receiver_id')->references('id')->on('users')->onDelete('cascade'); }); } public function down() { Schema::dropIfExists('chats'); } };

Run Migration

bash
php artisan migrate

πŸ›  Step 3: Secure Private Channels

1️⃣ Define Private Channel Authorization

Edit routes/channels.php:

php
use Illuminate\Support\Facades\Broadcast; Broadcast::channel('chat.{receiverId}', function ($user, $receiverId) { return (int) $user->id === (int) $receiverId; });

πŸ›  Step 4: Broadcast Events Securely

1️⃣ Create Chat Event

bash
php artisan make:event MessageSent

Modify MessageSent.php

php
namespace App\Events; use App\Models\Chat; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Queue\SerializesModels; class MessageSent implements ShouldBroadcastNow { use InteractsWithSockets, SerializesModels; public $chat; public function __construct(Chat $chat) { $this->chat = $chat; } public function broadcastOn() { return new PrivateChannel('chat.' . $this->chat->receiver_id); } public function broadcastWith() { return [ 'message' => $this->chat->message, 'sender_id' => $this->chat->sender_id, 'receiver_id' => $this->chat->receiver_id, 'timestamp' => $this->chat->created_at->toDateTimeString(), ]; } }

πŸ›  Step 5: Send Messages

1️⃣ Create ChatController.php

bash
php artisan make:controller ChatController

2️⃣ Store & Broadcast Messages Securely

Modify ChatController.php:

php
namespace App\Http\Controllers; use App\Events\MessageSent; use App\Models\Chat; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class ChatController extends Controller { public function sendMessage(Request $request) { $request->validate([ 'receiver_id' => 'required|exists:users,id', 'message' => 'required|string', ]); // Encrypt message before storing $chat = Chat::create([ 'sender_id' => Auth::id(), 'receiver_id' => $request->receiver_id, 'message' => encrypt($request->message), ]); // Broadcast event broadcast(new MessageSent($chat))->toOthers(); return response()->json(['message' => 'Sent successfully']); } }

πŸ”Ή Frontend: Vue 3 + TypeScript

πŸ›  Step 1: Setup Vue 3 + TypeScript

bash
npm create vue@latest chat-app-frontend cd chat-app-frontend npm install npm install @vueuse/core axios pusher-js laravel-echo

πŸ›  Step 2: Configure Laravel Echo

Modify src/plugins/echo.ts:

ts
import Echo from 'laravel-echo'; import Pusher from 'pusher-js'; window.Pusher = Pusher; const echo = new Echo({ broadcaster: 'pusher', key: 'reverb', wsHost: import.meta.env.VITE_APP_WS_HOST, wsPort: 6001, wssPort: 6001, forceTLS: false, disableStats: true, enabledTransports: ['ws', 'wss'] }); export default echo;

πŸ”Ή Modify .env

ini
VITE_APP_WS_HOST=localhost

πŸ›  Step 3: Chat Component

Create src/components/Chat.vue:

vue
<script setup lang="ts"> import { ref, onMounted } from 'vue'; import axios from 'axios'; import echo from '@/plugins/echo'; const userId = 1; // Replace with auth user ID const messages = ref<{ sender_id: number; message: string }[]>([]); const newMessage = ref(''); const sendMessage = async () => { await axios.post('http://localhost:8000/api/send-message', { receiver_id: 2, // Change to actual receiver message: newMessage.value }); newMessage.value = ''; }; onMounted(() => { echo.private(`chat.${userId}`) .listen('MessageSent', (e: any) => { messages.value.push(e); }); }); </script> <template> <div> <div v-for="msg in messages" :key="msg.message"> <strong v-if="msg.sender_id === userId">You:</strong> <strong v-else>Friend:</strong> {{ msg.message }} </div> <input v-model="newMessage" @keyup.enter="sendMessage" placeholder="Type a message..." /> <button @click="sendMessage">Send</button> </div> </template>

πŸ”Ή Deployment: Multi-Server Scaling

πŸ›  Step 1: Configure Load Balancer

Modify Nginx config:

nginx
upstream websocket_servers { server 192.168.1.101:6001; server 192.168.1.102:6001; } server { listen 80; server_name example.com; location /reverb { proxy_pass http://websocket_servers; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } }

πŸš€ Summary

Private Chat with Laravel 11 + Reverb + Redis
Vue 3 + TypeScript Frontend
Private Channels for Authentication
Load Balanced WebSockets for Multi-Server Scaling

πŸ’‘ Next Step: Want a Docker setup for full production deployment? πŸš€

Building a private chat real-time system using Laravel 11, Reverb, and Redis.

Here’s a step-by-step guide to building a private chat real-time system using Laravel 11, Reverb, and Redis.


Step 1: Install Laravel 11

If you haven’t already installed Laravel 11, create a new project:

bash
composer create-project laravel/laravel chat-app cd chat-app

Then, install dependencies:

bash
composer require predis/predis

Step 2: Install & Configure Laravel Reverb

1️⃣ Install Reverb

bash
php artisan reverb:install

2️⃣ Publish Reverb config file

bash
php artisan vendor:publish --tag=reverb-config

3️⃣ Update .env to use Redis broadcasting

env
BROADCAST_CONNECTION=redis QUEUE_CONNECTION=redis

4️⃣ Update config/broadcasting.php to use Redis

php
'connections' => [ 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], ],

5️⃣ Start Redis

bash
redis-server

Step 3: Create WebSocket Channel for Private Chat

1️⃣ Define a private channel in routes/channels.php

php
use Illuminate\Support\Facades\Broadcast; Broadcast::channel('chat.{receiverId}', function ($user, $receiverId) { return (int) $user->id === (int) $receiverId; });

πŸ’‘ This ensures only authenticated users can listen to their own chat events.


Step 4: Create a Chat Model & Migration

1️⃣ Generate Chat Model & Migration

bash
php artisan make:model Chat -m

2️⃣ Define the Schema in database/migrations/YYYY_MM_DD_create_chats_table.php

php
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::create('chats', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('sender_id'); $table->unsignedBigInteger('receiver_id'); $table->text('message'); $table->timestamps(); $table->foreign('sender_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('receiver_id')->references('id')->on('users')->onDelete('cascade'); }); } public function down() { Schema::dropIfExists('chats'); } };

3️⃣ Run Migration

bash
php artisan migrate

Step 5: Create Chat Event

1️⃣ Generate an Event

bash
php artisan make:event MessageSent

2️⃣ Edit app/Events/MessageSent.php

php
namespace App\Events; use App\Models\Chat; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Queue\SerializesModels; class MessageSent implements ShouldBroadcastNow { use InteractsWithSockets, SerializesModels; public $chat; public function __construct(Chat $chat) { $this->chat = $chat; } public function broadcastOn() { return new PrivateChannel('chat.' . $this->chat->receiver_id); } public function broadcastWith() { return [ 'message' => $this->chat->message, 'sender_id' => $this->chat->sender_id, 'receiver_id' => $this->chat->receiver_id, 'timestamp' => $this->chat->created_at->toDateTimeString(), ]; } }

πŸ’‘ This event will broadcast new messages to the receiver’s private channel.


Step 6: Create Chat Controller

1️⃣ Generate a Chat Controller

bash
php artisan make:controller ChatController

2️⃣ Edit app/Http/Controllers/ChatController.php

php
namespace App\Http\Controllers; use App\Events\MessageSent; use App\Models\Chat; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class ChatController extends Controller { public function sendMessage(Request $request) { $request->validate([ 'receiver_id' => 'required|exists:users,id', 'message' => 'required|string', ]); $chat = Chat::create([ 'sender_id' => Auth::id(), 'receiver_id' => $request->receiver_id, 'message' => $request->message, ]); broadcast(new MessageSent($chat))->toOthers(); return response()->json(['message' => 'Sent successfully']); } }

πŸ’‘ This method stores the message and broadcasts it to the receiver.


Step 7: Define API Route

Edit routes/api.php:

php
use App\Http\Controllers\ChatController; Route::middleware('auth:sanctum')->post('/send-message', [ChatController::class, 'sendMessage']);

πŸ’‘ Ensure your API uses auth:sanctum or another authentication method.


Step 8: Start Reverb WebSocket Server

1️⃣ Run Laravel Queues (Redis required)

bash
php artisan queue:work

2️⃣ Start Laravel Reverb

bash
php artisan reverb:start

Step 9: Frontend Integration (Example in JavaScript)

Here’s how to listen for messages using Laravel Echo:

1️⃣ Install Laravel Echo & Pusher JS

bash
npm install laravel-echo pusher-js

2️⃣ Configure Laravel Echo in resources/js/bootstrap.js

js
import Echo from 'laravel-echo'; import Pusher from 'pusher-js'; window.Pusher = Pusher; window.Echo = new Echo({ broadcaster: 'pusher', key: 'reverb', wsHost: window.location.hostname, wsPort: 6001, wssPort: 6001, forceTLS: false, disableStats: true, enabledTransports: ['ws', 'wss'] });

3️⃣ Listen for messages (Example in Vue.js or React)

js
window.Echo.private(`chat.${userId}`) .listen('MessageSent', (e) => { console.log("New message received:", e.message); });

Step 10: Test Everything

1️⃣ Start Laravel Backend

bash
php artisan serve

2️⃣ Start Reverb

bash
php artisan reverb:start

3️⃣ Send a Message using Postman or Frontend

json
POST /api/send-message { "receiver_id": 2, "message": "Hello, how are you?" }

4️⃣ Check if the receiver gets the real-time message!


How to Scale Laravel Reverb for Multi-Server?

  1. Ensure Redis is used for broadcasting (BROADCAST_CONNECTION=redis).
  2. Deploy Laravel on multiple servers.
  3. Run php artisan reverb:start on each server.
  4. Use a Load Balancer (e.g., Nginx, AWS ALB) to route WebSocket traffic.
  5. Enable Redis clustering for large-scale chat applications.

Summary

Laravel Reverb provides a native WebSocket solution for Laravel 11.
Redis is used to broadcast events across multiple servers.
Private Channels ensure secure messaging.
Frontend listens for messages using Laravel Echo.
For multi-server support, use Redis + Load Balancer.

Would you like a Docker setup for a production-ready chat app? πŸš€


XΓ‘c thα»±c Private Chat trong Laravel Reverb

Để Δ‘αΊ£m bαΊ£o chỉ người dΓΉng hợp lệ mα»›i cΓ³ thể lαΊ―ng nghe vΓ  nhαΊ­n tin nhαΊ―n trong Private Chat, Laravel sα»­ dα»₯ng Private Channels kαΊΏt hợp vα»›i cΖ‘ chαΊΏ xΓ‘c thα»±c.


1. XΓ‘c thα»±c Private Channel

Trong routes/channels.php:

php
use Illuminate\Support\Facades\Broadcast; Broadcast::channel('chat.{receiverId}', function ($user, $receiverId) { return (int) $user->id === (int) $receiverId; });

πŸ”Ή GiαΊ£i thΓ­ch:

  • Khi mα»™t người dΓΉng cα»‘ gαΊ―ng lαΊ―ng nghe kΓͺnh chat.{receiverId}, Laravel sαΊ½ gọi callback xΓ‘c thα»±c.
  • Chỉ khi $user->id === $receiverId, Laravel mα»›i cho phΓ©p người dΓΉng lαΊ―ng nghe kΓͺnh.
  • Điều nΓ y Δ‘αΊ£m bαΊ£o chỉ người nhαΊ­n tin nhαΊ―n mα»›i cΓ³ thể nghe tin nhαΊ―n Δ‘αΊΏn.

2. XΓ‘c thα»±c Người DΓΉng TrΖ°α»›c Khi Gα»­i Tin NhαΊ―n

Trong ChatController.php, Laravel bαΊ―t buα»™c user phαΊ£i Δ‘Δƒng nhαΊ­p để gα»­i tin nhαΊ―n:

php
public function sendMessage(Request $request) { $request->validate([ 'receiver_id' => 'required|exists:users,id', 'message' => 'required|string', ]); $chat = Chat::create([ 'sender_id' => Auth::id(), 'receiver_id' => $request->receiver_id, 'message' => $request->message, ]); broadcast(new MessageSent($chat))->toOthers(); return response()->json(['message' => 'Sent successfully']); }

πŸ”Ή GiαΊ£i thΓ­ch:

  • Auth::id() lαΊ₯y ID cα»§a user hiện tαΊ‘i (bαΊ―t buα»™c phαΊ£i login).
  • ChαΊ·n gα»­i tin nhαΊ―n Δ‘αΊΏn user khΓ΄ng tα»“n tαΊ‘i vα»›i exists:users,id.
  • Dα»― liệu chỉ được lΖ°u & phΓ‘t Δ‘i nαΊΏu user hợp lệ.

3. XΓ‘c thα»±c Khi LαΊ―ng Nghe KΓͺnh TrΓͺn Frontend

Laravel Echo sαΊ½ gα»­i request xΓ‘c thα»±c trΖ°α»›c khi lαΊ―ng nghe Private Channel.

VΓ­ dα»₯, trong Vue.js/React/JavaScript:

js
window.Echo.private(`chat.${userId}`) .listen('MessageSent', (e) => { console.log("Tin nhαΊ―n mα»›i:", e.message); });

πŸ“Œ LΖ°u Γ½:

  • Laravel sαΊ½ tα»± Δ‘α»™ng chαΊ·n kαΊΏt nα»‘i nαΊΏu user khΓ΄ng được phΓ©p nghe kΓͺnh chat.{receiverId}.
  • NαΊΏu user chΖ°a Δ‘Δƒng nhαΊ­p, Laravel sαΊ½ tα»« chα»‘i kαΊΏt nα»‘i.

4. Laravel XΓ‘c Thα»±c Private Channel NhΖ° ThαΊΏ NΓ o?

Khi frontend yΓͺu cαΊ§u lαΊ―ng nghe mα»™t Private Channel, Laravel sαΊ½:

  1. Kiểm tra user Δ‘Γ£ Δ‘Δƒng nhαΊ­p hay chΖ°a.
  2. ChαΊ‘y callback trong routes/channels.php để xem user cΓ³ quyền nghe khΓ΄ng.
  3. TrαΊ£ về lα»—i nαΊΏu khΓ΄ng hợp lệ, hoαΊ·c cho phΓ©p kαΊΏt nα»‘i nαΊΏu hợp lệ.

πŸ“Œ Tα»•ng KαΊΏt

Private Channel (chat.{receiverId}) Δ‘αΊ£m bαΊ£o chỉ người nhαΊ­n mα»›i được nghe tin nhαΊ―n.
Laravel Echo gα»­i yΓͺu cαΊ§u xΓ‘c thα»±c trΖ°α»›c khi cho phΓ©p kαΊΏt nα»‘i.
Backend yΓͺu cαΊ§u user phαΊ£i Δ‘Δƒng nhαΊ­p khi gα»­i tin nhαΊ―n (Auth::id()).
NαΊΏu khΓ΄ng xΓ‘c thα»±c, user khΓ΄ng thể nhαΊ­n tin nhαΊ―n private.

πŸ”Ή Vα»›i cΓ‘ch nΓ y, tin nhαΊ―n cα»§a user sαΊ½ an toΓ n vΓ  khΓ΄ng bα»‹ nghe lΓ©n. πŸš€

What is Laravel Reverb?

Laravel Reverb is a built-in WebSocket server introduced in Laravel 11 that allows you to create real-time applications without needing third-party services like Pusher or Laravel WebSockets.

πŸ”₯ In short: Laravel Reverb makes it easy to implement WebSockets in Laravel without any extra setup or costs.


πŸ“Œ Why use Laravel Reverb?

No need for Pusher → Reduces costs, no third-party dependencies.
Built into Laravel 11 → No need to install Laravel WebSockets.
High performance → Optimized for Laravel applications.
Easy to configure & deploy → Runs as a service within Laravel.


πŸ”§ How to Use Laravel Reverb?

1️⃣ Enable Reverb in Laravel

Open your .env file and set the broadcast driver to reverb:

env
BROADCAST_DRIVER=reverb

Start the Reverb WebSocket server with:

sh
php artisan reverb:start

By default, Reverb runs on port 6001.


2️⃣ Create an Event for Broadcasting Messages

πŸ“Œ Generate a new event:

sh
php artisan make:event MessageSent

πŸ“Œ Edit app/Events/MessageSent.php:

php
use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\SerializesModels; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class MessageSent implements ShouldBroadcast { use InteractsWithSockets, SerializesModels; public $message; public function __construct($message) { $this->message = $message; } public function broadcastOn() { return new Channel('chat'); } }

πŸ“Œ Explanation:

  • This event broadcasts on the chat channel.
  • When a message is sent, all clients listening to this channel will receive the event in real-time.

3️⃣ Update the Controller to Send Messages

πŸ“Œ Create ChatController:

sh
php artisan make:controller ChatController

πŸ“Œ Modify app/Http/Controllers/ChatController.php:

php
use Illuminate\Http\Request; use App\Events\MessageSent; class ChatController extends Controller { public function sendMessage(Request $request) { $message = [ 'user' => auth()->user()->name, 'message' => $request->message, ]; broadcast(new MessageSent($message))->toOthers(); return response()->json(['message' => $message]); } }

πŸ“Œ Explanation:

  • When a user sends a message, it broadcasts (broadcast()) the MessageSent event over WebSockets.

4️⃣ Add API Routes for Chat

πŸ“Œ Open routes/api.php and add:

php
use App\Http\Controllers\ChatController; Route::middleware('auth:sanctum')->post('/send-message', [ChatController::class, 'sendMessage']);

πŸ“Œ Now, the API will send messages in real-time!


5️⃣ Set Up Laravel Echo on Frontend

πŸ“Œ Install Laravel Echo & Reverb Client:

sh
npm install --save laravel-echo @laravel/reverb

πŸ“Œ Open resources/js/bootstrap.js and update:

js
import Echo from 'laravel-echo'; import Reverb from '@laravel/reverb'; window.Echo = new Echo({ broadcaster: Reverb, host: 'http://localhost:6001', }); window.Echo.channel('chat') .listen('MessageSent', (event) => { console.log("New message:", event.message); });

πŸ“Œ Explanation:

  • window.Echo.channel('chat') → Listens for the MessageSent event on the chat channel.
  • When a new message is received, it will log the message to the console.

πŸ“Œ Rebuild the frontend assets:

sh
npm run dev

6️⃣ Start WebSocket and Test Chat

πŸ“Œ Run Laravel server:

sh
php artisan serve

πŸ“Œ Start Laravel Reverb WebSocket:

sh
php artisan reverb:start

πŸ“Œ Send a message via API:

sh
curl -X POST "http://127.0.0.1:8000/api/send-message" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d '{"message":"Hello, world!"}'

πŸ“Œ If successful, the frontend console should display the message in real-time! πŸŽ‰


🎯 Summary

Laravel Reverb allows you to implement WebSockets without needing Pusher.
Simple setup—just start with php artisan reverb:start.
Works seamlessly with Laravel Echo for real-time events.
Integrates easily with Vue.js, React, or Blade templates.

πŸ‘‰ Now you have a real-time chat system in Laravel 11 without using any third-party services! πŸš€


Integrating Laravel Reverb with Vue 3 + TypeScript for Real-time Chat

Since you're using Vue 3 with TypeScript, you'll need to set up Laravel Echo with Reverb in Vue properly.


πŸ›  1. Install Dependencies

In your Vue 3 project, install Laravel Echo and Reverb client:

sh
npm install --save laravel-echo @laravel/reverb

πŸ“Œ 2. Set Up Laravel Echo in Vue 3 (TypeScript)

Create a new file src/utils/reverb.ts to handle WebSocket connections:

ts
import Echo from 'laravel-echo'; import Reverb from '@laravel/reverb'; declare global { interface Window { Echo: Echo; } } // Initialize Laravel Echo with Reverb window.Echo = new Echo({ broadcaster: Reverb, host: 'http://localhost:6001', // Ensure this matches your Laravel Reverb server }); export default window.Echo;

πŸ“Œ 3. Implement Chat Component in Vue 3

Create a new component src/components/Chat.vue:

vue
<script setup lang="ts"> import { ref, onMounted, onUnmounted } from 'vue'; import Echo from '@/utils/reverb'; import axios from 'axios'; interface Message { user: string; message: string; } const messages = ref<Message[]>([]); const newMessage = ref(''); const fetchMessages = async () => { try { const response = await axios.get<Message[]>('http://127.0.0.1:8000/api/messages', { headers: { Authorization: `Bearer YOUR_ACCESS_TOKEN` }, }); messages.value = response.data; } catch (error) { console.error('Error fetching messages:', error); } }; const sendMessage = async () => { if (!newMessage.value.trim()) return; try { await axios.post( 'http://127.0.0.1:8000/api/send-message', { message: newMessage.value }, { headers: { Authorization: `Bearer YOUR_ACCESS_TOKEN` } } ); newMessage.value = ''; // Clear input after sending } catch (error) { console.error('Error sending message:', error); } }; onMounted(() => { fetchMessages(); Echo.channel('chat') .listen('MessageSent', (event: { message: Message }) => { messages.value.push(event.message); }); }); onUnmounted(() => { Echo.leave('chat'); // Cleanup WebSocket connection }); </script> <template> <div class="chat-container"> <div class="messages"> <div v-for="(msg, index) in messages" :key="index" class="message"> <strong>{{ msg.user }}</strong>: {{ msg.message }} </div> </div> <div class="input-box"> <input v-model="newMessage" placeholder="Type a message..." @keyup.enter="sendMessage" /> <button @click="sendMessage">Send</button> </div> </div> </template> <style scoped> .chat-container { width: 400px; border: 1px solid #ddd; padding: 10px; border-radius: 5px; } .messages { max-height: 300px; overflow-y: auto; margin-bottom: 10px; } .message { padding: 5px; border-bottom: 1px solid #ddd; } .input-box { display: flex; gap: 10px; } input { flex: 1; padding: 5px; } button { padding: 5px 10px; cursor: pointer; } </style>

πŸ“‘ 4. Update Laravel Backend

Make sure you have these APIs in Laravel 11:

πŸ“Œ Modify routes/api.php:

php
use App\Http\Controllers\ChatController; Route::middleware('auth:sanctum')->group(function () { Route::post('/send-message', [ChatController::class, 'sendMessage']); Route::get('/messages', [ChatController::class, 'getMessages']); });

πŸ“Œ Modify app/Http/Controllers/ChatController.php:

php
use Illuminate\Http\Request; use App\Models\Message; use App\Events\MessageSent; class ChatController extends Controller { public function sendMessage(Request $request) { $message = Message::create([ 'user_id' => auth()->id(), 'message' => $request->message, ]); broadcast(new MessageSent($message))->toOthers(); return response()->json(['message' => $message]); } public function getMessages() { return Message::with('user')->latest()->take(50)->get(); } }

πŸ“Œ Modify app/Events/MessageSent.php:

php
use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\SerializesModels; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use App\Models\Message; class MessageSent implements ShouldBroadcast { use InteractsWithSockets, SerializesModels; public $message; public function __construct(Message $message) { $this->message = $message; } public function broadcastOn() { return new Channel('chat'); } }

πŸ”₯ 5. Start the Application

Run Laravel server:

sh
php artisan serve

Start Laravel Reverb WebSocket:

sh
php artisan reverb:start

Run Vue frontend:

sh
npm run dev

🎯 Summary

Laravel 11 Backend

  • Uses Laravel Reverb instead of Pusher.
  • API for sending & fetching messages.
  • Broadcasts messages using Laravel Echo.

Vue 3 + TypeScript Frontend

  • Uses Laravel Echo with Reverb for real-time messaging.
  • Listens for events and updates the chat UI.
  • API calls for sending & receiving messages.

πŸš€ Now you have a real-time chat system with Laravel Reverb + Vue 3 + TypeScript! πŸŽ‰

Thank you

Golang Advanced Interview Q&A