Joney Spark
Joney Spark

Reputation: 265

How to Make Realtime Notifications in Laravel Sanctum (SPA) - Private Channel Broadcasting?

I am using Laravel -v7.x and Vue CLI two different folders for Frontend and Backend. And using Laravel Sanctum (SPA) Authentication. I want to create real-time Notifications when some Events happen in my backend. and I already configured successfully the Websockets and the public Broadcasting working fine. But when I'm trying to using PrivateChannel then backend WebSockets can run the event on the WebSockets panel I see but could not get response on the console. Can you please help me? Below I share my code.

Vue CLI

#main.js


<script>
import Request from "./apis/Request"
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.VUE_APP_WEBSOCKETS_KEY,
    wsHost: process.env.VUE_APP_WEBSOCKETS_SERVER,
    encrypted: true,
    cluster: 'ap1',
    wsPort: 6001,
    forceTLS: false,
    disableStats: true,
    authorizer: (channel, options) => {
        console.log("OPTIONS>>", options);
        return {
            authorize: (socketId, callback) => {
                Request.POST_REQ('/broadcasting/auth', {
                    socket_id: socketId,
                    channel_name: channel.name
                })
                .then(response => {
                    callback(false, response.data);
                    console.log("RESPONSE>>", response);
                })
                .catch(error => {
                    callback(true, error);
                });
            }
        };
    },
})
</script>

#App.vue


<script>
import { mapGetters } from "vuex";
export default {
    computed: {
    ...mapGetters(["user"])
  },
    async mounted() {
        await window.Echo.private(`hello.user.${this.user.id}`).listen(
      "Hello",
      () => {
        console.log("OK");
      }
    );
    },
}
</script>

#vue env

#.env

VUE_APP_WEBSOCKETS_KEY = local
VUE_APP_WEBSOCKETS_SERVER = localhost

#Laravel

#Hello Event

#Hello.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 Hello implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct()
    {
        //
    }

    public function broadcastWith()
    {
        return [
            'hello' => 'Hello world'
        ];
    }

    public function broadcastOn()
    {
        return new PrivateChannel('hello.user.1');
    }
}

#BroadcastServiceProvider.php


<?php

namespace App\Providers;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\ServiceProvider;

class BroadcastServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Broadcast::routes();
        Broadcast::routes(["middleware" => ["auth:api"]]);

        require base_path('routes/channels.php');
    }
}

#channels.php


<?php

use Illuminate\Support\Facades\Broadcast;

Broadcast::channel('hello.user.{id}', function ($user, $id) {
    return (int) $user->id === (int) $id;
});

#laravel env

#.env

PUSHER_APP_ID=local
PUSHER_APP_KEY=local
PUSHER_APP_SECRET=local
PUSHER_APP_CLUSTER=ap1

#broadcasting.php


<?php

return [

'default' => env('BROADCAST_DRIVER', 'pusher'),

'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,
                'encrypted' => true,
                'host' => 'localhost',
                'port' => 6001,
                'scheme' => 'http'
            ],
        ],
    ],
];

#I run the event using tinker

php artisan tinker

event(new App\Events\Hello())

Upvotes: 0

Views: 1222

Answers (1)

You should place the Broadcast::routes method call within your routes/api.php file or change your existing BroadcastServiceProvider::boot() method to use sanctum as auth driver:

Broadcast::routes(['middleware' => ['auth:sanctum']]);

Upvotes: 1

Related Questions