Laravel Echo

An easy to use JavaScript WebSocket listener library.

Demo

A simple demo of websocket integration.

This demo will give you an idea of how websockets can be used to enrich your website experience with the use of real time events.

Show your support for your favorite emoji by clicking on it, this will trigger it to jump and spin with excitement, anyone else currently viewing this page will also see it jump and spin too!

If we are not busy right now, load this page up in another tab or on another device and see the power of websockets in action.

Click on your favorite emoji!

🎉
❤️
👀

Show Your Working

A quick walkthrough of how this works.

This walkthrough won't cover all aspects, but it should give you a good idea of how it all works.

My assumptions, are at the very least, are that you have Laravel setup with Reverb (or other websocket server), Livewire and Echo installed and configured.

The Event

To enable Laravel to broadcast our event to end users via WebSockets, we need to create a new event class, you can do this by running the following command in your console.

php artisan make:event EmojiClicked

This will create the file /app/Events/EmojiClicked.php , there are a few things to update in this file.

Broadcast Type

Change the implements ShouldBroadcast to ShouldBroadcastNow , this will tell Laravel to broadcast the event as soon as it received it, rather then queue it which can add a delay.

Broadcast Channel

In the broadcastOn() function, change the channel to Channel and provide the name demos , this tells Laravel to broadcast the event on the public channel called demos .

Storage Variables

Finally, define a variable to hold some data about the event, in this case we want to know which emoji the user clicked, so declare a public string variable called $emoji and also add some code to set this in the events constructor function.

The resulting file should look like this:

1<?php
2 
3namespace App\Events;
4 
5use Illuminate\Broadcasting\Channel;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
8use Illuminate\Foundation\Events\Dispatchable;
9use Illuminate\Queue\SerializesModels;
10 
11class EmojiClicked implements ShouldBroadcastNow
12{
13 use Dispatchable, InteractsWithSockets, SerializesModels;
14 
15 public string $emoji;
16 
17 /**
18 * Create a new event instance.
19 */
20 public function __construct(
21 string $emoji,
22 )
23 {
24 $this->emoji = $emoji;
25 }
26 
27 /**
28 * Get the channels the event should broadcast on.
29 *
30 * @return array<int, \Illuminate\Broadcasting\Channel>
31 */
32 public function broadcastOn(): array
33 {
34 return [
35 new Channel('demos'),
36 ];
37 }
38}

The View

We now need to start creating our frontend for the user to interact with, this will be done in two parts, the first is defining a blade template and the second is to define a Livewire component.

You can create a view with the following artisan command.

php artisan make:view demos/echo

This will create the file /resources/views/demos/echo.blade.php , you can now build this up to fit your design, below is a condensed version of my file, notice the Livewire and JavaScript parts, these are the most important.

1<x-layouts.html
2 title="Laravel Echo - Demos"
3 pageTitle="Laravel Echo"
4 pageTagLine="An easy to use JavaScript WebSocket listener library."
5>
6 <x-content-container class="w-full mb-8">
7 <div class="mb-8 text-left">
8 <h2 class="text-2xl mb-2">Demo</h2>
9 <p class="mb-2 text-slate-500">A simple demo of websocket integration.</p>
10 <x-gradent-under-line />
11 </div>
12 
13 <div class="text-left">
14 <x-content-text class="mb-8 text-2xl text-center">
15 Click on your favorite emoji!
16 </x-content-text>
17 
18 <!-- Include the Livewire component -->
19 <livewire:demos.echo-emoji />
20 
21 <!--
22 JavaScript to setup a listener on the demos
23 channel to listen for the "EmojiClicked" event.
24 
25 When an event is received, add, and then remove
26 a CSS class 0.5s later to the emoji that was clicked.
27 -->
28 <script>
29 document.addEventListener("DOMContentLoaded", function() {
30 window.Echo.channel('demos').listen('EmojiClicked', e => {
31 let emoji = $('#demo-echo-emoji-' + e.emoji);
32 if (! emoji.hasClass('animated-element')) {
33 emoji.addClass('animated-element');
34 setTimeout(function () {
35 emoji.removeClass('animated-element');
36 }, 500);
37 }
38 })
39 });
40 </script>
41 </div>
42 </x-content-container>
43</x-layouts.html>

The Livewire Component

Now for the second part of our frontend, the Livewire component, this will handle the clicks and triggering of the event.

You can create a Livewire component with the following artisan command.

php artisan make:livewire Demos/EchoEmoji

This will have created two new files, /app/Livewire/Demos/EchoEmoji.php and /resources/views/livewire/demos/echo-emoji.blade.php , these files are very simple, the first handles the server code or logic and the other is the view displayed to the user.

1<?php
2 
3namespace App\Livewire\Demos;
4 
5use App\Events\EmojiClicked;
6use Livewire\Attributes\Renderless;
7use Livewire\Component;
8 
9class EchoEmoji extends Component
10{
11 public function render()
12 {
13 return view('livewire.demos.echo-emoji');
14 }
15 
16 #[Renderless]
17 public function click(string $emoji): void
18 {
19 EmojiClicked::dispatch($emoji);
20 }
21}
1<div class="flex w-full justify-around text-5xl md:text-8xl">
2 <div>
3 <span
4 class="cursor-pointer select-none block "
5 id="demo-echo-emoji-party"
6 wire:click.throttle.500ms="click('party')">🎉</span>
7 </div>
8 
9 <div>
10 <span
11 class="cursor-pointer select-none block"
12 id="demo-echo-emoji-heart"
13 wire:click.throttle.500ms="click('heart')">❤️</span>
14 </div>
15 
16 <div>
17 <span
18 class="cursor-pointer select-none block"
19 id="demo-echo-emoji-eyes"
20 wire:click.throttle.500ms="click('eyes')">👀</span>
21 </div>
22</div>

The Route

Finally, to enable people to access this page, we need to define a route in the /routes/web.php file.

Route::get('/demos/echo', function () {
return view('demos/echo');
})->name('demos.echo');