0

I am using laravel-websockets package by beyondcode and it is working great for public channels. However when i switch to a private channel, the event is fired but my client cannot listen. I have discovered the channel authorization callback is not called i'm not sure why. My event:

<?php

namespace App\Events;

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

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

    public $message;

    public function __construct($message)
    {
        $this->message = $message;
    }

    public function broadcastOn(): PrivateChannel
    {
        return new PrivateChannel("message.".$this->message->receiver);
    }
}

My broadcast route for authorization of the channel in api.php

Route::post("/broadcasting/auth",function(){
    \Illuminate\Support\Facades\Log::info("Route is reached"); //this is called
    Broadcast::channel("message.{user_id}",function($user,$message){
        \Illuminate\Support\Facades\Log::info("Authorizing channel"); //this is not called
        return true;
    });
})->middleware(["auth:sms"]);

And my angular client that listens for the event:

const {value } = await Preferences.get({key:"auth_token"});
 let echo = new Echo({
        broadcaster: 'pusher',
        key: 'pusher_key',
        wsHost: environment.websocker_server_development,
        wsPort: 6001,
        wssPort:6001,
        encrypted:true,
        forceTLS: false,
        bearerToken:value,
        authEndpoint:"http://192.168.43.221:8000/api/broadcasting/auth",
        auth:{
          headers:{
            "Authorization":`Bearer ${value}`,
            'Content-Type': 'application/json'
          }
        }
      });
 echo.private(`message.${this.user.id}`).listen("MessageSentEvent",(e)=>{
       console.log(e)
      })

Again this works perfectly when a public channel is used but a private wouldn't work. I suspect it wouldnt work,i suspect it is becuase the Broadcast::channel callback is not called. Why is it not called?

Noble Eugene
  • 523
  • 1
  • 5
  • 15
  • As far as I remember, broadcasting in `PrivateChannel` uses routes in *channels.php* – Abdulla Nilam Oct 04 '22 at 09:07
  • yes @AbdullaNilam But i keep getting a persistent 403 error from so i disabled the default broadcasting routes configuration and used my own – Noble Eugene Oct 04 '22 at 09:10
  • Even if you use your own, you must define it in *channels.php*. In *channels.php* after `Broadcast::channel('App.User.{id}', function ($user, $id) {` add `return true` and check whether it works. – Abdulla Nilam Oct 04 '22 at 09:13
  • yes @AbdullaNilam, i tried that. Was getting a 403 error – Noble Eugene Oct 04 '22 at 09:17

1 Answers1

0

Ive found a solution. First is to use channels.php file for the routes:

Broadcast::channel("message.{id}",function(){
    \Illuminate\Support\Facades\Log::info("Authorizing channel");
    return true;
});

And most importantly, i had to add the api middleware so that the broadcast authenticator would stop expecting a session request:

    public function boot()
    {
        Broadcast::routes(["prefix"=>"api","middleware"=>["api","auth:sms"]]);

        require base_path('routes/channels.php');
    }
Noble Eugene
  • 523
  • 1
  • 5
  • 15