Laravel Realtime with Ably & Laravel Livewire

Howdy!

One of the things I love about Livewire, is the seamless integration with Laravel Echo, which makes listening to real time events a breeze.

In this tutorial, wel will see how to integrate Livewire with Ably.

Author

NOTE: : The reason why I chose Ably, because of their generous free tier.
NOTE: : This guide will assume you have Laravel & Livewire installed and already configured.

So let's get started.
Firs thing to do is to create an account in Ably, so head there and create your account.
Then, you have to create an application, give it a name, and we are good to go.
The next thing to do, is to grab the API key.
From the Ably dashboard, head to API Keys, you will find 2 keys, we are interested in the first one

API Keys in Ably dashboard
Click on Show, then click on Copy, and let's go to our project.
In your favorite text editor, open the .env file.
At the bottom of the file, add this entry :

ABLY_KEY=UDAfQA.yFhVpQ:*************************

The API key you copied should go to ABLY_KEY.
After setting up the key, now let's install the Ably Broadcaster.
In your terminal run this command :

composer require ably/laravel-broadcaster

After installing it, in your .env file, set BROADCAST_DRIVER as ably.
Then, go to config/app.php and uncomment

        App\Providers\BroadcastServiceProvider::class,

Now, let's install Ably Laravel Echo.
In your terminal, run this command

npm install @ably/laravel-echo ably

After the installation, put the following code, that will allow us to make connection to Ably SDK.
You can put this code in the bootstrap.js file, or in any other JavaScript file

import Echo from '@ably/laravel-echo';
import * as Ably from 'ably';

window.Ably = Ably;
window.Echo = new Echo({
    broadcaster: 'ably',
});
//this bit of code is optional, it's used to check the conntection to ably
window.Echo.connector.ably.connection.on(stateChange => {
    if (stateChange.current === 'connected') {
        console.log('connected to ably server');
    }
});

After setting up everything, now let's go create our Livewire components.
We will create a Sender component, a receiver component, and an event.
We will start with the event. In your terminal, run this command

 php artisan make:event TriggerEvent

The output of the command will be a class located under App/Events. Let's open the class, and edit it so it will be as follows:

class TriggerEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

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

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [
            new Channel('public-events'),
        ];
    }
}

The TriggerEvent class must implement ShouldBroadcast interface. Then in the constructor we passed a message, so we can get it later in the receiver component.
Then in the broadcastOn function, we returned an array of channels to broadcast on.
In our example, we returned an instance of Channel, which is a public channel, with the name of public-events.
The name is used to listen to it whenever an event is triggered.
Now let's get to our components.
The sender component will trigger the event, and the receiver will listen to it and update the UI.
So in your terminal, run those commands to create the components.

 php artisan livewire:make Sender
 php artisan livewire:make Receiver

Our focus for now is the sender component. In the view file we will have an input text and button to trigger the event.
In the sender.blade.php, put the following code :

<div>
    This is the sender component, the notification will be triggered from here.
    <div>
        <input type="text" wire:model='message'>
    </div>
    <button wire:click='trigger'>Trigger</button>
</div>

In the above code, we have a model binded input to a property called message and the button is binded to a method called trigger.
Now in the Sender.php class, our code will be as follows :

...
    public $message;
    
    public function render()
    {
        return view('livewire.sender');
    }

    public function trigger()
    {
        TriggerEvent::dispatch($this->message);
    }
...

Now, let's head to the Receiver component.
In the view file, we will have the following :

<div>
    Breaking News :
    <h1>{{ $message }}</h1>
</div>

A dead simple UI, with a message property.
But the magic will happen, in the php class.
So open the Receiver.php class, and let's edit it as follows:

...
    protected $listeners = ['echo:public-events,TriggerEvent' => 'responseToEvent'];

    public $message;

    public function render()
    {
        return view('livewire.receiver');
    }

    public function responseToEvent($event)
    {
        $this->message = $event['message'];
    }
...

The first thing to add is the $listeners property, which is the array responsible for defining our listeners.
In that array, echo:public-events,TriggerEvent where public-events is the name of the channel we defined earlier, and TriggerEvent is the name of the event, also we have responseToEvent which is the function will be fired whenever TriggerEvent is triggered.
Then we have a property called message which will be updated in the responseToEvent method.

And that's it, if everything went good, we will have the following result

If you have any questions, feel free to comment here, or DM me on Twitter

Thank you for following the tutorial, and I will see you in other ones.