Laravel Realtime with Ably & Laravel Livewire
Tags: realtime, laravel, livewire, ably
Published: 2023-05-21 13:49:24

Welcome, 
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.
> **_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](https://ably.com), 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8uasl1uvmsme04mwj9go.png)
Click on Show, then click on Copy, and let's go to our project.
In your favorite text editor, open the <code>.env</code> 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 

 {% embed https://vimeo.com/828761869 %}
If you have any questions, feel free to comment here, or DM me on [Twitter](https://twitter.com/Koossaayy)
[Original Post](https://koossaayy.tn/laravel-realtime-with-ably-laravel-livewire-)
Thank you for following the tutorial, and I will see you in other ones.