Search code examples
phplaravelpusher

Pusher Doesn't Broadcast on Private Channels -PHP/Laravel


I have set up Pusher and Laravel Echo for my app to notify users on some event firings.

I have tested to see whether setup is working by broadcasting on a "Public Channel" and successfully saw that is works.

Here is the event itself:

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

  public $item;

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

  public function broadcastOn()
  {
      return new Channel('items');
  }
}

Public channel:

Broadcast::channel('items', function ($user, $item) {
  return true;
});

app/resources/assets/js/bootstrap.js:

import  Echo from 'laravel-echo';
window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'my_key',
    cluster: 'eu',
    encrypted: true
});

And Laravel Echo registration: (it is in the "head" section of my main layout that event firing view extends from.)

<head>
<meta charset="utf-8">


<meta name="csrf-token" content="{{ csrf_token() }}">

<script src="{{ asset('js/app.js') }}"></script>

<script>
    window.Laravel = {'csrfToken': '{{csrf_token()}}'}

    window.Echo.channel('items')
    .listen('ItemUpdated', function(e) {
        console.log("It is working:)");
    });

</script>
</head>

Now, this setup works for public channel broadcasting, but when i try to broadcast on a private channel, i get

  //updated "ItemUpdated" event broadcastOn() method
  public function broadcastOn()
  {
      return new PrivateChannel('items');
  }

//updated laravel echo registering
<script>
window.Laravel = {'csrfToken': '{{csrf_token()}}'}

window.Echo.private('items')
.listen('ItemUpdated', function(e) {
    console.log("It is working:)");
});

 //console logged error
Pusher couldn't get the auth user from :myapp 500

I have checked the outgoing network requests from developer console and find out pusher is trying to "POST" to

http://localhost:8000/broadcast/auth

but it gets a 500 error code.

Thought that might help figure out the problem.

What should i do ?


Solution

  • So i figured out how should i implement private channel listening and got it working.

    My mistake was in wildcard choice.

    I was telling it to use the authenticated user id as a wildcard instead of item id that changes are applied to.

    Therefore, this below channel registration was always returning false and was causing Pusher to throw 500 auth couldn't found.

      Broadcast::channel('items.{item}', function ($user, \App\Item $item) {
        return $user->id === $item->user_id;
    });
    

    So, here is the working version:

    Event being broadcasted:

    //ItemUpdated event
    
    class ItemUpdated implements ShouldBroadcast
    {
       use Dispatchable, InteractsWithSockets, SerializesModels;
    
       public $item;
    
       public function __construct(Item $item)
       {
           $this->item = $item;
       }
    
       public function broadcastOn()
       {
           return new PrivateChannel('items.'.$this->item->id);
       }
    }
    

    Channel registration:

    app\routes\channels.php    
    
    Broadcast::channel('items.{item}', function ($user, \App\Item $item) {
        return $user->id === $item->user_id;
    });
    

    Laravel Echo registration:

    <head>
    
    <meta name="csrf-token" content="{{ csrf_token() }}">
    
    
    <script>
        window.Laravel = {'csrfToken': '{{csrf_token()}}'}
    
        window.Echo.private(`items.{{{$item->id}}}`)
        .listen('ItemUpdated', function(e) {
            console.log("It is working!");
        });
    
    </script>
    

    Thank you all for pointers.