The Power of Instant Connectivity Modern users expect applications to respond in real time. Stale data and manual refreshes are relics of the past. Laravel Echo serves as the bridge between your server-side events and your front-end interface. It is a robust JavaScript library that abstracts the complexity of WebSockets, allowing you to subscribe to channels and listen for broadcasts with a clean, expressive API. By integrating with a driver like Laravel Reverb, Echo turns your static UI into a living ecosystem. Prerequisites and Tooling To follow this guide, you should be comfortable with JavaScript and the Laravel framework. You will need a configured broadcasting driver—**Laravel Reverb** is the modern standard—and the Echo library installed via NPM. Ensure your `BROADCAST_DRIVER` is set correctly in your environment files to allow the back end to push events to the socket server. Implementing Private Notifications Private channels ensure that sensitive data only reaches the intended recipient. Laravel Echo simplifies this by using the `.private()` method. ```javascript Echo.private(`App.Models.User.${userId}`) .notification((notification) => { console.log(notification.data); addNotificationToUI(notification); }); ``` In this snippet, we target a specific user's channel. The `.notification()` helper is a specialized listener that automatically catches Laravel's broadcasted notifications, saving you from manually defining event names for standard alerts. Mastering Presence Channels Presence channels extend private channels by adding awareness of who else is currently subscribed. This is vital for "Who's Online" lists or collaborative editing. You define these in `channels.php` and join them using the `.join()` method. ```javascript Echo.join('online') .here((users) => { this.users = users; }) .joining((user) => { this.users.push(user); }) .leaving((user) => { this.users = this.users.filter(u => u.id !== user.id); }); ``` The `here` callback returns everyone currently in the channel, while `joining` and `leaving` act as reactive hooks to keep your UI updated as people come and go. Syntax Notes and Best Practices Laravel Echo relies heavily on callback functions to handle incoming data. Always ensure your channel names in the JavaScript match your definitions in `channels.php` exactly. Use template literals to inject dynamic IDs into channel strings. Most importantly, keep your event payloads light; send only the data needed to update the UI to minimize bandwidth overhead.
Laravel Echo
Products
The Laravel channel (12 mentions) drives the positive consensus, highlighting the library as an essential bridge for frontend event hooks in "Echo - Tune into Laravel broadcasts" and emphasizing its utility within "Laravel Cloud Has Managed Reverb Now."
- Dec 9, 2025
- Nov 13, 2025
- Jul 24, 2025
- May 24, 2025
- May 16, 2025
Overview of Real-Time Web Architecture Traditional web applications operate on a request-response cycle. This model, while reliable, creates a significant lag when users need instant updates, such as chat messages or live status indicators. Developers often resort to **short polling**, where the client repeatedly hits the server to ask for new data. This is inefficient; it wastes server resources and creates a "stuttering" user experience. Laravel Reverb solves this by providing a first-party, high-performance websocket server for the Laravel ecosystem. It creates an open "pipe" between the client and server, allowing bidirectional data flow. When something changes on the backend, the server pushes it to the client instantly. This guide explores how Reverb leverages an asynchronous event loop to handle tens of thousands of concurrent connections on a single PHP process. Prerequisites To follow this tutorial, you should be comfortable with: * **PHP 8.2+**: Knowledge of modern PHP syntax and the Composer package manager. * **Laravel 11**: Familiarity with the slimmed-down application skeleton and Artisan commands. * **JavaScript Basics**: Understanding of how to handle events in the browser. * **Networking Concepts**: Basic awareness of HTTP vs. WebSockets and UDP vs. TCP. Key Libraries & Tools * Laravel Reverb: The core websocket server package. * Laravel Echo: The JavaScript library used to subscribe to channels and listen for events on the frontend. * ReactPHP: A low-level library providing the asynchronous event loop that powers Reverb. * **Datagram Factory**: A ReactPHP component for UDP communication (used for hardware integration). * **FFmpeg**: A multimedia framework used here to process and stream video frames. * Redis: Used as a Pub/Sub mechanism to scale Reverb horizontally across multiple servers. Under the Hood: The Event Loop Reverb doesn't use the typical synchronous PHP execution model. Instead, it relies on the ReactPHP event loop. This loop is essentially an infinite `while(true)` loop that performs three critical tasks on every "tick": 1. **Future Ticks**: It processes tasks deferred from previous iterations to avoid blocking the main thread. 2. **Timers**: It executes scheduled tasks, such as pruning stale connections or heartbeats. 3. **I/O Streams**: It monitors active sockets for incoming data. By using non-blocking I/O, a single PHP process can keep thousands of connections "parked" in memory, only using CPU cycles when a connection actually sends or receives data. This is how Reverb achieves its massive scalability. Code Walkthrough: Hardware Control via Websets In advanced implementations, you can use Reverb's event loop to interface with hardware, like a drone, using UDP. 1. Initializing the Custom Server To gain access to the raw loop, you might hand-roll a command instead of using the default `reverb:start`. ```php // Getting the underlying ReactPHP loop $loop = \React\EventLoop\Loop::get(); // Starting the Reverb server with the loop $server = ReverbServerFactory::make($loop, $config); ``` 2. Communicating via UDP Drones often require UDP for low-latency commands. We use the `Datagram\Factory` to create a client within the Reverb process. ```php $factory = new \React\Datagram\Factory($loop); $factory->createClient('192.168.10.1:8889')->then(function ($socket) { // Send an initialization command $socket->send('command'); // Store the socket in a service for later use app()->singleton(FlyService::class, fn() => new FlyService($socket)); }); ``` 3. Handling Client Whispers To send commands from the UI (like "flip" or "move") without a full Laravel controller cycle, we can intercept **Client Whispers**. These are lightweight messages sent from one client to others that Reverb normally just passes through. ```php // Listening for Reverb's MessageReceived event Event::listen(MessageReceived::class, function ($event) { $message = $event->message; if (str_starts_with($message, 'client-fly-')) { $command = str_replace('client-fly-', '', $message); // Resolve our UDP service and fire the command to the hardware app(FlyService::class)->send($command); } }); ``` Syntax Notes * **Non-blocking logic**: Never use `sleep()` or long-running `foreach` loops inside the event loop. This stops the entire server. Use timers or chunking instead. * **Singleton Pattern**: When working with hardware sockets (UDP/TCP), bind the connection as a singleton in the Laravel container so it persists across different parts of the application. * **Client Whispers**: These always start with the `client-` prefix by convention in Laravel Echo. Practical Examples * **Telemetry Dashboards**: Streaming sensor data (battery, temperature, altitude) from IoT devices to a web UI in real-time. * **Video Streaming**: Using FFmpeg to pipe video frames into a Reverb event, base64 encoding the image chunks, and rendering them onto a `<canvas>` element on the frontend. * **Live Collaborative Tools**: Real-time cursor tracking or document editing where sub-100ms latency is required. Tips & Gotchas * **Scaling with Redis**: If you run multiple Reverb servers behind a load balancer, you must use the Redis publish/subscribe adapter. This ensures that an event received by Server A is broadcasted to clients connected to Server B. * **Avoid Deadlocks**: Do not perform synchronous HTTP requests or database queries inside the `MessageReceived` listener unless they are wrapped in an asynchronous wrapper. Doing so will block the event loop and potentially crash the websocket server. * **Memory Usage**: Since connections stay in memory, monitor your server's RAM. Laravel Pulse integrates directly with Reverb to provide real-time monitoring of connection counts and message throughput.
Sep 6, 2024Overview Laravel Reverb marks a significant milestone in the Laravel ecosystem. As a first-party, high-performance WebSocket server, it eliminates the historical friction of integrating real-time features into PHP applications. Traditionally, developers had to rely on third-party services like Pusher or complex Node.js setups to handle bi-directional communication. Reverb changes this by bringing the entire infrastructure under the Laravel umbrella, allowing for seamless integration with Livewire and Alpine.js. This guide explores how to build a collaborative environment where users can see each other's actions instantly. We will implement a shared toggle switch and a real-time cursor tracking system similar to collaborative tools like Figma. By the end of this tutorial, you will understand how to manage state across multiple clients, broadcast events efficiently, and deploy a production-ready WebSocket server using Laravel Forge. Prerequisites To follow along effectively, you should be comfortable with: * **PHP and Laravel 11**: Basic understanding of routing, controllers, and Eloquent. * **Livewire Volt**: Familiarity with the class-based API for single-file components. * **JavaScript (Alpine.js)**: Basic knowledge of reactive front-end directives like `x-data` and `x-on`. * **Terminal/CLI**: Ability to run Artisan commands and manage NPM packages. * **Local Environment**: Laravel Herd is highly recommended for its built-in Reverb support, but a standard Laravel setup works as well. Key Libraries & Tools * Laravel Reverb: The core WebSocket server handling real-time data transmission. * Livewire Volt: A single-file component syntax for Livewire that keeps logic and templates unified. * Laravel Echo: The JavaScript library used to subscribe to channels and listen for events on the client side. * Alpine.js: Handles local UI state and ensures "optimistic" updates for a snappier user experience. * **Font Awesome**: Provides the visual icons for our cursor effects. Code Walkthrough: The Multi-Player Toggle Our first task is creating a toggle switch that stays in sync for every user currently on the site. We use a combination of database caching and event broadcasting to ensure state persistence. 1. Scaffolding the Component Generate the Volt component using the following command: ```bash php artisan make:volt toggle ``` In the component, we define the `toggle_switch` property and use the `mount` method to retrieve the initial state from the cache. This ensures that if a new user joins, they see the current state immediately. ```php public bool $toggle_switch = false; public function mount() { $this->toggle_switch = Cache::get('toggle_switch', false); } ``` 2. The Broadcasting Event We need a dedicated event class to signal the WebSocket server. Create it with `php artisan make:event SwitchFlipped`. Crucially, this event must implement `ShouldBroadcastNow` to bypass the queue and send data immediately. ```php class SwitchFlipped implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; public function __construct(public bool $toggle_switch) {} public function broadcastOn(): array { return [new Channel('switch')]; } public function broadcastWith(): array { return ['toggle_switch' => $this->toggle_switch]; } } ``` 3. Triggering the Flip Inside the Volt component, the `flipSwitch` method updates the cache and broadcasts the new state to all other connected clients. ```php public function flipSwitch() { Cache::forever('toggle_switch', $this->toggle_switch); broadcast(new SwitchFlipped($this->toggle_switch))->toOthers(); } ``` On the front end, we use Alpine.js to entangle the local state with the Livewire property. This creates an "optimistic UI" where the switch moves instantly for the user who clicked it, while the server call happens in the background. ```html <div x-data="{ localToggle: $wire.entangle('toggle_switch') }"> <input type="checkbox" x-model="localToggle" x-on:change="$wire.flipSwitch()"> </div> ``` Syntax Notes: Attributes and Entanglement The `On` Attribute Livewire provides a powerful PHP attribute, `#[On]`, which allows your component to listen for client-side events directly within the class. When using Reverb, we prefix the event name with `echo:`. This tells Livewire to listen to the WebSocket channel rather than a standard internal event. ```php #[On('echo:switch,SwitchFlipped')] public function handleBroadcast($payload) { $this->toggle_switch = $payload['toggle_switch']; } ``` State Entanglement The `$wire.entangle()` method is the bridge between Alpine.js (client-side) and Livewire (server-side). It creates a two-way binding. If you change a variable in Alpine, it reflects in Livewire, and vice versa. This is critical for real-time apps because it allows the UI to react to broadcasts without full page reloads. Practical Examples: Advanced Cursor Tracking Beyond simple toggles, we can track mouse movements to create a collaborative workspace. This requires calculating cursor positions relative to the screen center so that users on different monitor sizes see the pointer in the correct logical position. Calculating Relative Position In our JavaScript, we calculate the offset from the center of the viewport. This prevents the cursor from appearing "broken" when users have different browser window dimensions. ```javascript const relativeX = (e.clientX - (window.innerWidth / 2)) / (window.innerWidth / 2); const relativeY = (e.clientY - (window.innerHeight / 2)) / (window.innerHeight / 2); ``` We then send these coordinates to the Livewire component, which broadcasts them via a `MouseMoved` event. To prevent overwhelming the server with hundreds of events per second, we implement a slight throttle or check to ensure the mouse has actually moved a significant distance before broadcasting. Smooth Cursor Animation Directly binding a `div` to the coordinates received from a broadcast can look choppy due to network latency. To fix this, we use a requestAnimationFrame loop in Alpine.js to interpolate the cursor's current position toward the target position, creating a fluid, professional feel. Tips & Gotchas * **Queue vs. Now**: By default, Laravel events are queued. In real-time apps, this can cause a noticeable lag. Always use `ShouldBroadcastNow` for interactions that require immediate feedback, like mouse movement or chat messages. * **Environment Variables**: Ensure your `.env` file has `BROADCAST_CONNECTION=reverb`. If you're using Herd, it manages the credentials for you, but on a manual setup, you must verify the `REVERB_APP_ID` and `REVERB_APP_KEY` match your server configuration. * **Browser Backgrounding**: Browsers often throttle JavaScript in background tabs. We added a `visibilitychange` listener to stop broadcasting cursor data when a user switches tabs. This saves server resources and keeps the active user count accurate. * **Sticky Sessions**: When deploying to production, ensure your load balancer (if using one) supports WebSockets. Reverb handles the connections, but your infrastructure must allow the long-lived HTTP connection to remain open.
Jul 9, 2024Overview Modern development requires reducing boilerplate while maintaining performance. This guide explores recent updates to Laravel that simplify URL generation, enhance rate-limiting flexibility, and introduce anonymous event broadcasting. These changes allow developers to write cleaner code without sacrificing the robust features that define the framework. Prerequisites To follow this tutorial, you should have a solid grasp of **PHP 8.2+** and basic experience with Laravel. Knowledge of **Facades**, **Event Broadcasting**, and **Blade templating** will help you understand how these improvements integrate into your existing projects. Key Libraries & Tools * Laravel Framework: The core PHP framework receiving these updates. * Blade: Laravel's powerful templating engine, now optimized for high-volume component rendering. * Reverb: A first-party WebSocket server for Laravel that facilitates real-time communication. Code Walkthrough Fluent URL Query Generation Previously, appending query parameters required manual string manipulation or passing arrays to specific route helpers. The new `URL::query()` method makes this process expressive. ```php // Generating a URL with multiple query parameters $url = URL::query('products', [ 'page' => 1, 'active' => true, 'sort' => 'name' ]); // Output: https://your-app.test/products?page=1&active=1&sort=name ``` This method automatically handles the `?` separator and URL-encoding, ensuring your links are always valid. Anonymous Event Broadcasting In previous versions, broadcasting required creating a dedicated Event class. Now, you can use the `Broadcast` facade to send data to channels on the fly, similar to how anonymous notifications work. ```php use Illuminate\Support\Facades\Broadcast; Broadcast::on("private-orders.1") ->as("OrderStatusUpdated") ->with(['status' => 'delivered']) ->send(); ``` The `as()` method allows you to define the event name that the frontend (e.g., Laravel Echo) listens for, while `with()` contains your data payload. Syntax Notes * **Method Chaining**: The `Broadcast` facade now supports a fluent interface, making the logic easy to read at a glance. * **Rate Limiting**: The `RateLimiter::decrement()` method has been added to complement the `increment()` method, allowing for more granular manual control over user attempts. Practical Examples * **Dynamic Filtering**: Use `URL::query()` to build search result pages where users toggle multiple filters like category, price range, and availability. * **Real-time Alerts**: Use anonymous broadcasting for one-off system alerts or status updates where creating a permanent Event class would be overkill. Tips & Gotchas * **Performance**: Blade recently received a **20% performance boost** when rendering thousands of components. If your application is component-heavy, updating to the latest version of Laravel provides an immediate win. * **Event Names**: When using anonymous broadcasting, ensure the string passed to `as()` exactly matches what your frontend is listening for, as you no longer have the class name as a default reference.
Apr 30, 2024The Reverb Revolution Laravel Reverb marks a significant shift in how developers handle real-time communication. Traditionally, setting up WebSockets required third-party services like Pusher or complex Node.js setups. Reverb brings this capability into the first-party Laravel ecosystem, offering a high-performance, PHP-first WebSocket server that integrates seamlessly with existing broadcasting tools. Installation and Core Setup Getting started requires just a single command. Run `php artisan install:broadcast` to kick off the process. This command is a powerhouse; it publishes your configuration files, creates the `routes/channels.php` file, and installs Laravel Echo. During installation, the CLI prompts you to enable Reverb. Once confirmed, you'll find a new `reverb.php` config file and updated environment variables for your ID, Key, and Secret. Backend Logic: Events and Channels To push data, you must define an Event that implements the `ShouldBroadcast` interface. Use the `broadcastOn` method to specify your channel. ```python public function broadcastOn(): array { return [ new PrivateChannel('orders.' . $this->order->id), ]; } ``` Start your server with `php artisan reverb:start`. This spins up the engine that listens for these dispatched events and pushes them to connected clients. Frontend Integration with Echo On the client side, Alpine.js works beautifully with Laravel Echo to react to incoming data. You listen for the event and update your local state immediately. ```javascript Echo.private(`orders.${this.orderId}`) .listen('OrderShipmentStatusUpdate', (e) => { this.status = e.status; this.updateProgressBar(); }); ``` Securing Data via Private Channels Security is non-negotiable. While public channels work for general updates, order statuses require Private Channels. You must define authorization logic in `routes/channels.php`. This ensures a user can only listen to updates for orders they actually own, preventing data leaks across your application.
Mar 21, 2024Overview Laravel Reverb solves a persistent headache in modern web development: the reliance on expensive third-party services like Pusher for real-time features. By providing a first-party, high-performance WebSocket server, Laravel allows developers to handle thousands of concurrent connections directly within their own infrastructure. This eliminates external latency and reduces monthly overhead while keeping the entire stack under your control. Prerequisites To follow this guide, you should have a solid grasp of the PHP language and basic familiarity with the Laravel framework. You should understand how events work in a backend context and possess a basic understanding of front-end state management using Alpine.js. Key Libraries & Tools - **Laravel Reverb**: The WebSocket server that manages real-time socket connections. - **Laravel Echo**: A JavaScript library that makes it painless to subscribe to channels and listen for events. - **Alpine.js**: A lightweight JavaScript framework used here to manage UI reactions and connection states. - **Artisan**: Laravel's command-line interface used to boot the server. Code Walkthrough First, we define a backend event that implements the `ShouldBroadcast` interface. This tells Laravel to push the event to the socket server instead of just executing it locally. ```php class UserReacted implements ShouldBroadcast { public function broadcastOn() { return new PresenceChannel('reverb'); } } ``` The `broadcastOn` method is critical; it defines the channel users must join. On the front end, we use Laravel Echo within an Alpine.js component to listen for these broadcasts. ```javascript Echo.join('reverb') .here((users) => { this.count = users.length; }) .listen('UserReacted', (e) => { this.triggerAnimation(e.type); }); ``` This snippet joins a `PresenceChannel`, updates a live user counter, and triggers a UI reaction whenever a `UserReacted` event arrives. Syntax Notes When implementing real-time features, pay close attention to the **Interface Implementation**. Using `implements ShouldBroadcast` is a non-negotiable step for event broadcasting. Additionally, the **Closure Dispatch** pattern in your Livewire or PHP components allows for clean, reactive triggers when users interact with the UI. Tips & Gotchas Always remember to start your server. Your code will not throw an error, but reactions will never appear if you forget to run `php artisan reverb:start`. For production environments, ensure your server is configured to handle the high volume of file descriptors required for thousands of concurrent WebSocket connections.
Feb 5, 2024Overview Modern users demand instant feedback. Whether it is a chat message or a background job finishing, waiting for a page refresh feels like an eternity. Laravel bridges this gap using **WebSockets**, allowing your server to push updates directly to the client the moment they happen. This tutorial explores how to move from static requests to a dynamic, event-driven architecture. Prerequisites To follow along, you should have a solid grasp of PHP and basic Laravel concepts like Events and Listeners. You will also need Node.js installed for managing front-end dependencies via NPM. Key Libraries & Tools * Pusher: A hosted service that handles the heavy lifting of WebSocket connections. * **Laravel Echo**: A JavaScript library that makes it painless to subscribe to channels and listen for events. * **Pusher PHP SDK**: The bridge that allows your server-side code to communicate with Pusher. Code Walkthrough 1. Server Configuration First, pull in the necessary package and configure your `.env` file with your Pusher credentials. You must also uncomment the `BroadcastServiceProvider` in `config/app.php` to enable the broadcasting routes. ```bash composer require pusher/pusher-php-server ``` 2. Preparing the Event To make an event broadcastable, implement the `ShouldBroadcast` interface. This tells Laravel to push the event into your queue for broadcasting instead of just executing local listeners. ```python class OrderPlaced implements ShouldBroadcast { public function __construct(public Order $order) {} public function broadcastOn() { return new PrivateChannel('orders.' . $this->order->id); } } ``` 3. Front-end Integration On the client side, use Laravel Echo to listen. We use the `private` method to ensure only authorized users access this specific data stream. ```javascript Echo.private(`orders.${orderId}`) .listen('OrderPlaced', (e) => { console.log('Order update received:', e.order); }); ``` Syntax Notes Notice the `broadcastOn` method. It defines the transmission path. Using `PrivateChannel` triggers an authorization check, whereas `Channel` creates a public stream. Laravel automatically uses the event's class name as the broadcast name, so keep your naming conventions consistent between PHP and JavaScript. Practical Examples * **Notifications**: Alerting a user that their report is ready for download. * **Live Dashboards**: Updating stock prices or server health metrics without refreshing. * **Collaboration**: Showing "User is typing..." indicators in a shared workspace. Tips & Gotchas Always remember to run `php artisan queue:work`. Broadcasting is an asynchronous task; if your queue worker isn't running, your events will sit in the database or Redis and never reach the client. For local development, ensure your `BROADCAST_DRIVER` is set to `pusher` rather than `log`.
Oct 19, 2021Simplify Event Handling with Echo Keeping your frontend in sync with your backend often leads to a messy trail of event listeners. Historically, Laravel Echo required a separate callback for every single event you wanted to track. This quickly becomes unmanageable as your application grows. The community solved this with the new `listenToAll` method. Instead of registering dozens of individual listeners, you can now catch every broadcasted event in a single, unified callback. This provides a centralized hub to filter data and trigger UI updates, drastically reducing boilerplate code in your JavaScript assets. Automated Maintenance and On-Demand Storage Database bloat is a silent performance killer, especially within the `failed_jobs` table. The framework now includes a `queue:prune-failed` command, allowing you to automatically wipe data older than a specific threshold, such as 24 hours. This keeps your disk space clear without manual intervention. On the storage front, the Laravel filesystem component now supports on-demand disk configuration via the `build` method. This is a massive win for multi-tenant architectures. Instead of hardcoding every possible storage path in a config file, you can generate a disk instance at runtime with custom roots or configurations. It allows you to point to specific tenant directories or external buckets dynamically without messing with global state. Streamlined Billing and Infrastructure Configuring payment webhooks is often the most tedious part of integrating Laravel Cashier. A new Artisan command now automates the entire Stripe webhook setup process. It creates the endpoint on your Stripe account and subscribes to necessary events in seconds. Meanwhile, Laravel Vapor has revamped its internal deployment logic. By utilizing job batching, the platform now executes deployment steps in parallel. This significantly cuts down wait times during production pushes. Finally, Laravel Forge has upgraded its security standard, enabling **TLS 1.3** by default on new servers to ensure faster handshakes and robust encryption.
Jun 23, 2021