Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Sunshine And March Vibes (2025 Wallpapers Edition)

      May 16, 2025

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      May 16, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      May 16, 2025

      How To Prevent WordPress SQL Injection Attacks

      May 16, 2025

      Microsoft has closed its “Experience Center” store in Sydney, Australia — as it ramps up a continued digital growth campaign

      May 16, 2025

      Bing Search APIs to be “decommissioned completely” as Microsoft urges developers to use its Azure agentic AI alternative

      May 16, 2025

      Microsoft might kill the Surface Laptop Studio as production is quietly halted

      May 16, 2025

      Minecraft licensing robbed us of this controversial NFL schedule release video

      May 16, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      The power of generators

      May 16, 2025
      Recent

      The power of generators

      May 16, 2025

      Simplify Factory Associations with Laravel’s UseFactory Attribute

      May 16, 2025

      This Week in Laravel: React Native, PhpStorm Junie, and more

      May 16, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Microsoft has closed its “Experience Center” store in Sydney, Australia — as it ramps up a continued digital growth campaign

      May 16, 2025
      Recent

      Microsoft has closed its “Experience Center” store in Sydney, Australia — as it ramps up a continued digital growth campaign

      May 16, 2025

      Bing Search APIs to be “decommissioned completely” as Microsoft urges developers to use its Azure agentic AI alternative

      May 16, 2025

      Microsoft might kill the Surface Laptop Studio as production is quietly halted

      May 16, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»Adding Real Time Chat to Laravel Using Reverb & Vue

    Adding Real Time Chat to Laravel Using Reverb & Vue

    July 1, 2024

    Laravel, the web artisan’s favorite PHP framework, has just got a whole new powerful tool in its arsenal: Reverb. Among the official packages of Laravel, this WebSocket server application would seamlessly let you integrate real-time features in your Laravel-based applications, thereby taking interaction to a whole new level.

    What is Laravel Reverb?

    Reverb acts as a mediator between your Laravel-based application and its users. It establishes two-way, real-time communication based on WebSockets technology that allows web pages to receive updates on the server without a complete page refresh. This means that your users experience your application more dynamically and responsively.

    Key Features of Laravel Reverb

    Blazing Speed: Provides outstanding performance for real-time information with no lags.

    Scalability: Grow with your applications to handle increased user traffic.

    Seamless Integration: It works with broadcasting features added to Laravel and Laravel Echo to make development simple.

    Push Updates: Push updates, messages, or events to clients to share your information instantly.

    Built-in Security: Data encryption and authentication assurance for security communication

    Adding Laravel Reverb to Your Chat Project

    With Laravel Reverb, you can build dynamic chat applications. The messages are posted instantly, making users involved comprehensively. Here’s a breakdown of the steps involved:

    Step 1: Setting Up Your Laravel Project:

    Ensure you have a Laravel application set up (version 11 or above is recommended).

    If you’re starting fresh, use composer create-project laravel/laravel your-chat-app-name.

    Step 2: Install and Configure Reverb:

    Install Laravel Reverb by running the following command:

    php artisan install:broadcasting

    Once you’ve installed Reverb, you can now modify its configuration from the config/reverb.php file. To establish a connection to Reverb, a set of Reverb “application” credentials must be exchanged between the client and server. These credentials are configured on the server and are used to verify the request from the client. You can define these credentials using the following environment variables:

    BROADCAST_DRIVER=reverb
    REVERB_APP_ID=my-app-id
    REVERB_APP_KEY=my-app-key
    REVERB_APP_SECRET=my-app-secret

    It also automatically creates echo.js in the resources/js directory.

    import Echo from ‘laravel-echo’;

    import Pusher from ‘pusher-js’;
    window.Pusher = Pusher;

    window.Echo = new Echo({
    broadcaster: ‘reverb’,
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? ‘https’) === ‘https’,
    enabledTransports: [‘ws’, ‘wss’],
    });

    Follow the Laravel documentation for configuration steps specific to your application server https://laravel.com/docs/11.x/reverb

    Step 3: Running a Server

    You can launch the Reverb server by using the reverb:start Artisan command:

    php artisan reverb:start

    By default, the Reverb server will be started at 0.0.0.0:8080, which makes it accessible from all network interfaces.

    If you want to set a specific host or port, you can use the –host and –port options when starting the server.

    php artisan reverb:start –host=127.0.0.1 –port=9000

    You can also define REVERB_SERVER_HOST and REVERB_SERVER_PORT environment variables in your application’s .env configuration file.

    Step 4: Setup Database

    Open your .env file and adjust the settings to set up your database. Here’s an example using SQLite for simplicity:

    DB_CONNECTION=sqlite
    DB_DATABASE=/path/to/database.sqlite

    You can create an SQLite database by simply running:

    touch /path/to/database.sqlite

    For this demo, we’ll create five predefined rooms. Let’s start by generating a model ChatMessage with migration for a chat_messages table.

    php artisan make:model ChatMessage –migration

    To make it simpler, only create name attributes for this model and migrate it.

    Schema::create(‘chat_messages’, function (Blueprint $table) {
    $table->id();
    $table->foreignId(‘receiver_id’);
    $table->foreignId(‘sender_id’);
    $table->text(‘text’);
    $table->timestamps();
    });

    php artisan migrate

    Now, let’s add the necessary relationships in the ChatMessage model. Open the ChatMessage.php file in the app/Models directory and update it as follows:

    <?php

    namespace AppModels;

    use IlluminateDatabaseEloquentFactoriesHasFactory;
    use IlluminateDatabaseEloquentModel;

    class ChatMessage extends Model
    {
    use HasFactory;

    protected $fillable = [
    ‘sender_id’,
    ‘receiver_id’,
    ‘text’
    ];

    public function sender()
    {
    return $this->belongsTo(User::class, ‘sender_id’);
    }

    public function receiver()
    {
    return $this->belongsTo(User::class, ‘receiver_id’);
    }
    }

    Step 5: Create Event

    To handle the broadcasting of messages, we’ll create an event called MessageSent. This event will implement Laravel’s ShouldBroadcastNow interface, which allows for immediate broadcasting over WebSockets without queuing. Follow these steps to create and set up the event:

    Create a new PHP file in the AppEvents directory and name it MessageSent.php.

    Open the newly created file and add the following code:

    <?php

    namespace AppEvents;

    use AppModelsChatMessage;
    use IlluminateBroadcastingInteractsWithSockets;
    use IlluminateBroadcastingPrivateChannel;
    use IlluminateContractsBroadcastingShouldBroadcastNow;
    use IlluminateFoundationEventsDispatchable;
    use IlluminateQueueSerializesModels;

    class MessageSent implements ShouldBroadcastNow
    {
    use Dispatchable;
    use InteractsWithSockets;
    use SerializesModels;

    /**
    * Create a new event instance.
    */
    public function __construct(public ChatMessage $message)
    {
    //
    }

    /**
    * Get the channels the event should broadcast on.
    *
    * @return array<int, IlluminateBroadcastingChannel>
    */
    public function broadcastOn(): array
    {
    return [
    new PrivateChannel(“chat.{$this->message->receiver_id}”),
    ];
    }
    }

    Step 6: Create a Private Channel Route

    The channels.php file in Laravel applications plays a crucial role in defining broadcast channels used for real-time communication features.

    <?php

    use IlluminateSupportFacadesBroadcast;

    Broadcast::channel(‘chat.{id}’, function ($user, $id) {
    return (int) $user->id === (int) $id;
    });

    This code defines a private channel named chat.{id} using Laravel’s Broadcast facade. Private channels restrict access based on user authentication and authorization logic.

    Step 7: Defining Routes

    1. Chat Room Route:

    Route::get(‘/chat/{friend}’, function (User $friend) {
    return view(‘chat’, [
    ‘friend’ => $friend
    ]);
    })->middleware([‘auth’])->name(‘chat’);

    This route is responsible for rendering the chat interface. It accepts a dynamic parameter {friend} representing the user’s chat partner.

    3. Get Chat Messages Route:

    Route::get(‘/messages/{friend}’, function (User $friend) {
    return ChatMessage::query()
    ->where(function ($query) use ($friend) {
    $query->where(‘sender_id’, auth()->id())
    ->where(‘receiver_id’, $friend->id);
    })
    ->orWhere(function ($query) use ($friend) {
    $query->where(‘sender_id’, $friend->id)
    ->where(‘receiver_id’, auth()->id());
    })
    ->with([‘sender’, ‘receiver’])
    ->orderBy(‘id’, ‘asc’)
    ->get();
    })->middleware([‘auth’]);

    This route retrieves chat messages exchanged between the authenticated user and the specified friend ({friend}). The query ensures it retrieves messages where either the user is the sender or receiver, including both directions of the conversation.

    4. Send Chat Message Route:

    Route::post(‘/messages/{friend}’, function (User $friend) {
    $message = ChatMessage::create([
    ‘sender_id’ => auth()->id(),
    ‘receiver_id’ => $friend->id,
    ‘text’ => request()->input(‘message’)
    ]);

    broadcast(new MessageSent($message));

    return $message;
    });

    After creating the message, it leverages Laravel’s broadcasting functionality using broadcast(new MessageSent($message)). This line broadcasts the newly created message to all connected users through Reverb, enabling real-time chat functionality.

    Step 8: Creating the Blade View

    To render the chat interface, you’ll need to create a Blade view file. Create a new file named chat.blade.php in the resources/views directory and add the following code:

    <x-app-layout>
    <x-slot name=”header”>
    <h2 class=”text-xl font-semibold leading-tight text-gray-800″>
    {{ $friend->name }}
    </h2>
    </x-slot>

    <div class=”py-12″>
    <div class=”mx-auto max-w-7xl sm:px-6 lg:px-8″>
    <div class=”overflow-hidden bg-white shadow-sm sm:rounded-lg”>
    <div class=”p-6 bg-white border-b border-gray-200″>
    <chat-component
    :friend=”{{ $friend }}”
    :current-user=”{{ auth()->user() }}”
    />
    </div>
    </div>
    </div>
    </div>
    </x-app-layout>

    The key element here is <chat-component :friend=”{{ $friend }}” :current-user=”{{ auth()->user() }}” />. This line renders a Vue.js component named chat-component.

    Step 8: Create a Chat Component

    <template>
    <div>
    <div class=”flex flex-col justify-end h-80″>
    <div ref=”messagesContainer” class=”p-4 overflow-y-auto max-h-fit”>
    <div
    v-for=”message in messages”
    :key=”message.id”
    class=”flex items-center mb-2″
    >
    <div
    v-if=”message.sender_id === currentUser.id”
    class=”p-2 ml-auto text-white bg-blue-500 rounded-lg”
    >
    {{ message.text }}
    </div>
    <div v-else class=”p-2 mr-auto bg-gray-200 rounded-lg”>
    {{ message.text }}
    </div>
    </div>
    </div>
    </div>
    <div class=”flex items-center”>
    <input
    type=”text”
    v-model=”newMessage”
    @keydown=”sendTypingEvent”
    @keyup.enter=”sendMessage”
    placeholder=”Type a message…”
    class=”flex-1 px-2 py-1 border rounded-lg”
    />
    <button
    @click=”sendMessage”
    class=”px-4 py-1 ml-2 text-white bg-blue-500 rounded-lg”
    >
    Send
    </button>
    </div>
    <small v-if=”isFriendTyping” class=”text-gray-700″>
    {{ friend.name }} is typing…
    </small>
    </div>
    </template>

    <script setup>
    import axios from “axios”;
    import { nextTick, onMounted, ref, watch } from “vue”;

    const props = defineProps({
    friend: {
    type: Object,
    required: true,
    },
    currentUser: {
    type: Object,
    required: true,
    },
    });

    const messages = ref([]);
    const newMessage = ref(“”);
    const messagesContainer = ref(null);
    const isFriendTyping = ref(false);
    const isFriendTypingTimer = ref(null);

    watch(
    messages,
    () => {
    nextTick(() => {
    messagesContainer.value.scrollTo({
    top: messagesContainer.value.scrollHeight,
    behavior: “smooth”,
    });
    });
    },
    { deep: true }
    );

    const sendMessage = () => {
    if (newMessage.value.trim() !== “”) {
    axios
    .post(`/messages/${props.friend.id}`, {
    message: newMessage.value,
    })
    .then((response) => {
    messages.value.push(response.data);
    newMessage.value = “”;
    });
    }
    };

    const sendTypingEvent = () => {
    Echo.private(`chat.${props.friend.id}`).whisper(“typing”, {
    userID: props.currentUser.id,
    });
    };

    onMounted(() => {
    axios.get(`/messages/${props.friend.id}`).then((response) => {
    console.log(response.data);
    messages.value = response.data;
    });

    Echo.private(`chat.${props.currentUser.id}`)
    .listen(“MessageSent”, (response) => {
    messages.value.push(response.message);
    })
    .listenForWhisper(“typing”, (response) => {
    isFriendTyping.value = response.userID === props.friend.id;

    if (isFriendTypingTimer.value) {
    clearTimeout(isFriendTypingTimer.value);
    }

    isFriendTypingTimer.value = setTimeout(() => {
    isFriendTyping.value = false;
    }, 1000);
    });
    });
    </script>

    This Vue.js component manages the chat interface’s dynamic behaviour. It displays a scrollable message list, styled differently based on the sender (current user or friend). It provides an input field for composing new messages and a button to send them. It leverages axios for making HTTP requests to fetch initial messages and send new ones.

    Real-time functionality is achieved using Laravel Echo:

    It listens for broadcasted MessageSent events to update the message list whenever a new message arrives.

    It utilizes whispers on private channels to notify the chat partner about the user’s typing activity and receive similar notifications from the friend.

    Step 9: Run Project

    To run the Laravel project, we need to execute the following command:

    php artisan serve

    For starting front:

    npm run dev

    Run reverb:

    php artisan reverb:start

    Source Code

    You can find the source code for this Laravel Reverb chat implementation in the following GitHub repository: https://github.com/qirolab/laravel-reverb-chat

    By utilizing Laravel Reverb, developers can ensure their applications remain responsive and dynamic, providing real-time updates and interactions that modern users expect. Happy coding!

    The post Adding Real Time Chat to Laravel Using Reverb & Vue appeared first on Laravel News.

    Join the Laravel Newsletter to get all the latest Laravel articles like this directly in your inbox.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleCLI Experiments : DataTable (Part 2)
    Next Article Maximizing Your Dreamforce 2024 Experience: Perficient’s Pro Tips

    Related Posts

    Machine Learning

    Salesforce AI Releases BLIP3-o: A Fully Open-Source Unified Multimodal Model Built with CLIP Embeddings and Flow Matching for Image Understanding and Generation

    May 16, 2025
    Security

    Nmap 7.96 Launches with Lightning-Fast DNS and 612 Scripts

    May 16, 2025
    Leave A Reply Cancel Reply

    Continue Reading

    The State of PHP 2024

    Development

    I went hands-on with dozens of indie games at Gamescom Latam last week — You need to wishlist these 7 titles right now

    News & Updates

    Why Conversational AI Chatbots Are a Game-Changer for Your Business

    Development

    plakativ stretches PDF or raster image across multiple pages

    Linux

    Highlights

    Development

    Task-Specific Data Selection: A Practical Approach to Enhance Fine-Tuning Efficiency and Performance

    November 21, 2024

    In the evolving field of machine learning, fine-tuning foundation models such as BERT or LLAMA…

    CVE-2024-53569 – Volmarg Personal Management System Stored XSS

    April 22, 2025

    13 Free AI Courses on AI Agents in 2025

    January 1, 2025

    I found the ultimate laptop accessory for power users – and it’s gloriously designed

    December 23, 2024
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.