Flutter Pusher with  Laravel WebSockets 🛰
Tags: laravel, flutter, websockets, socketio
Published: 2022-02-12 21:10:18

Hey everyone, 
Today I'm going to demonstrate achieving **WebSocket** Communication between **Laravel** web application and **Flutter** mobile application using our own **WebSocket** Server.

This article shall be divided as following:

1. Laravel & Web Socket Server Configuration ⚙️
2. Flutter Configuration ⚙️

let's get start 🔥..

## 1.Laravel Setup
### Fresh Laravel Installation ✨
Their is different ways to install Laravel, one is using Composer as following:
```bash
composer update --prefer-dist
composer create-project laravel/laravel LaraIo --prefer-dist
```
After being satisfied with your fresh installation, we shall go to next step.
### Installing Laravel-WebSockets 🛰
```bash
composer require beyondcode/laravel-websockets
```
```bash
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
```

Now it's time to migrate some tables related to WebSockets that holds the Statistical data over your server

```bash
php artisan migrate
```
Then, Publishing Configuration file
```bash
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
```
Here we will get configuration file under `/config/websockets.php` which holds configurations of the hole WebSocket Server.

For Now, we will not change any thing in this `websockets.php` file. On the other hand we shall update our configuration in the `.env` file.

### Pusher Replacement 🎤
As mentioned on the official web site of **LaravelWebSockets** that The easiest way to get started with Laravel WebSockets is by using it as a Pusher replacement.
Then we need to install the official Pusher PHP SDK Package.

```bash
composer require pusher/pusher-php-server "~3.0"
```
now it's time to do configuration thing :
- Head to `config/broadcasting.php` and update the file as following:
```php
'connections' => [

        'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER'),
//                'useTLS' => true, comment it
                'host'  => '127.0.0.1', // for localhost installation
                'port'  => 6001, // standard port
                'scheme'    => 'http',
            ],
        ],
```
- Make sure to apply this configurations `.env`
```php
BROADCAST_DRIVER=pusher

PUSHER_APP_ID="AnyPusherID"
PUSHER_APP_KEY="AnyPusherKey"
PUSHER_APP_SECRET="AnyPusherSecret"
PUSHER_APP_CLUSTER="mt1"
```
- Run WebSocket Server
```bash
php artisan websocket:serve
```

### Now It's Time to Test Our WebSocket Server 🐛
We will need to create an event, let us call it TestEvent
```bash
php artisan make:event TestEvent
```
This will generate file looks like this 
```php
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class TestEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('channle');
    }
}
```

Lets do some changes
```diff
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;


- class TestEvent {
+ class TestEvent implements ShouldBroadcast {

    use Dispatchable, InteractsWithSockets, SerializesModels;
+ 
+    public $message = '';
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct($message)
+    {
+        $this->message = $message;
+    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
-        return new Channel('channle');
+        return ['test-channel'];
    }
+ 
+    public function broadcastAs(){
+        return 'test-event';
+    }
}

```
Note That WebSocket Server come with monitoring web page that give us live updates about what is currently happening.
We can Access this page Through 
`LaraIO.test/laravel-websockets`
That looks like this:

![Laravel WebSockets Dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbe3f84m9iycup7guvko.jpg)

You only have to Press Connect button to start listening for updates

Now We need to fire our `TestEvent` by using Laravel Tinker
```bash
php artisan tinker
```
```php
event(new \App\Events\TestEvent("Hello World"));
```
Verify that the event triggered by checking WebSocket Dashboard.
Now It's Time to move on to then next Section of our Article.

## 2.Flutter Configurations 
### Installing Packages 📦
heading to your flutter application opening `pubspec.yaml` file and add the following dependency
```yaml
dependencies:
  flutter:
    sdk: flutter
  laravel_flutter_pusher: ^0.0.4
```
Then do `Pub get` Command to install it. And you can access the Official Page on pub.dev [Here](https://pub.dev/packages/laravel_flutter_pusher)
 
### Writing Some Code ⌨️
Inside the `Lib` folder create `services/PusherWebSockets/pusher.dart` file with the following code:
```dart
import 'package:laravel_flutter_pusher/laravel_flutter_pusher.dart';

class PusherService {
    /// Init Pusher Listener
  LaravelFlutterPusher initPusher(String appKey, String host, int port, String cluster) {
    return LaravelFlutterPusher(
        appKey,
        PusherOptions(
            host: host,
            port: port,
            encrypted: false,
            cluster: cluster
        ),
        enableLogging: true,
        onConnectionStateChange: (status){ print(status); }
    );
  }
  /// Subscribe to Channel & Event
  void listen(LaravelFlutterPusher pusher, String channel, String event){
    pusher.subscribe(channel).bind(event, (event) {
      print("SocketID: ");
      print(pusher.getSocketId());
      print(event);
    });
  }
}

```

Then we could use This Service Class as following
```dart
/// Init Pusher Listener
LaravelFlutterPusher pusher = pusherService.initPusher("AnyPusherKey", "10.0.2.2", 6001, "mt1");

/// Subscribe to Channel
pusherService.listen(pusher, "test-channel", "test-event");
```
If we fire the TestEvent again using Tinker, We will get console log in android studio as following
```console
I/flutter (10748): SocketID: 
I/flutter (10748): 106601092.70854279
I/flutter (10748): {message: Hello World"}
```
So far so GOOD. 👏🏻
I hope you enjoy it.
Good Luck 🍀