Private channel not working with Laravel echo server

10,554

Solution 1

You can set REDIS_PREFIX to NULL to remove the prefix else if it has a value then you must set keyPrefix in the echo server config.

If REDIS_PREFIX = NULL then do not add keyPrefix.


Important Notice

When using broadcastAs(), the call to listen('') call must start with a DOT

At this moment the behavior when keyPrefix is used is unknown, if you use the prefix settings, please comment on the outcome of the DOT requirement.

https://laravel.com/docs/6.x/broadcasting#broadcast-name

public function broadcastAs()
{
    return 'server.created';
}
.listen('.server.created', function (e) {
    ....
});

I would check the DOT + PREFIX combo my self but I feel Laravel Echo is going to give me a heart attack if I work on it any longer.


If you do not use broadcastAs() then the naming will fallback to the event class name, in this case there is no DOT prefix injected, see the setup below:

laravel-echo-server.json

{
    "host": "127.0.0.1",
    "port": "6001",
    "protocol": "http",

    "database": "redis",

    "databaseConfig": {
        "redis": {
            "host": "127.0.0.1",
            "port": 6379,
            "db": 0,
            "keyPrefix": "VALUE OF REDIS_PREFIX"
        }
}

/app/Events/MyExample.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;

class MyExample implements ShouldBroadcastNow
{

  private $id;

  public $payload;

  public function __construct($id, $payload)
  {
    $this->id = $id;
    $this->payload = $payload;
  }

  public function broadcastOn()
  {
    return new PrivateChannel('example.' . $this->id);
  }

}

Trigger an event (PHP)


use App\Events\MyExample

$payload = [
 'duck' => 'sauce',
 'Bass' => 'Epic'
];

event(new MyExample($id, $payload))

Listening for event (JavaScript)

Echo.private(`example.${id}`).listen('MyExample', event => {

  console.log('payload', event.payload)

})

Solution 2

Try to change this line:

$this->$receiverId = $receiverId;

To this line:

$this->receiverId = $receiverId;

In your PrivateMessageEvent __construct()

Update:

Try to use use a fixed channel id like this:

window.Echo.private('private-chat.1')

I suggest you also to use presence channel, are private too but with more features, i.e.:

Echo.join('private-chat.1')
   .listen('PrivateMessageEvent', (e) => {
    console.log(e);
});

If you use a dinamic channel number like you use, i.e.:

window.Echo.private(`private-chat.${receiverId}`)

You have to give receiverId a value in javascript, this declaration is a generic room listener but receiverId should be defined, ${receiverId} is a string interpolation.

You can define receiverId in the template before inluding app.js, for example, using blade syntax:

<script>
   receiverId = {{ $receiverId }};
</script>

Another think: I want to be clear that, in all the code above, receiverId represent the id of the chat/room a client want join to not the ID of the receiving user.

Share:
10,554
Parth Vora
Author by

Parth Vora

Updated on June 04, 2022

Comments

  • Parth Vora
    Parth Vora almost 2 years

    I'm getting this JS error on the console:

    app.js:167 Uncaught ReferenceError: receiverId is not defined

    Here is my complete code:

    PrivateChatController:

    event(new PrivateMessageEvent($chat, $receiverId));
    

    PrivateMessageEvent:

    namespace App\Events;
    
    use Illuminate\Broadcasting\Channel;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Broadcasting\PrivateChannel;
    use Illuminate\Broadcasting\PresenceChannel;
    use Illuminate\Foundation\Events\Dispatchable;
    use Illuminate\Broadcasting\InteractsWithSockets;
    use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
    use App\User;
    use App\PrivateChat;
    
    class PrivateMessageEvent implements ShouldBroadcast
    {
        use Dispatchable, InteractsWithSockets, SerializesModels;
    
        public $privateChat, $receiverId;
        /**
         * Create a new event instance.
         *
         * @return void
         */
        public function __construct(PrivateChat $privateChat, $receiverId)
        {
            $this->privateChat = $privateChat;
            $this->receiverId = $receiverId;
        }
    
        /**
         * Get the channels the event should broadcast on.
         *
         * @return Channel|array
         */
        public function broadcastOn()
        {
            return new PrivateChannel('private-chat.' . $this->receiverId);
        }
    }
    

    Bootstrap.js

    import Echo from "laravel-echo"
    
    window.Echo = new Echo({
        broadcaster: 'socket.io',
        host: window.location.hostname + ':6001'
    });
    
    window.Echo.private(`private-chat.${receiverId}`)
        .listen('PrivateMessageEvent', (e) => {
            console.log(e);
    });
    

    channels.php

    Broadcast::channel('private-chat.{receiverId}', function ($user, $receiverId) {
        return true; // this is just for debugging to allow anyone to listen on this channel
        //return $user->id === $receiverId;
    });
    

    laravel-echo-server.json

    {
        "authHost": "http://localhost",
        "authEndpoint": "/broadcasting/auth",
        "clients": [],
        "database": "redis",
        "databaseConfig": {
            "redis": {},
            "sqlite": {
                "databasePath": "/database/laravel-echo-server.sqlite"
            }
        },
        "devMode": true,
        "host": null,
        "port": "6001",
        "protocol": "http",
        "socketio": {},
        "sslCertPath": "",
        "sslKeyPath": ""
    }
    

    In background queue:work and laravel-echo-server are already running

    Upon firing that event, I'm getting this message on the laravel-echo-server console:

    Channel: private-private-chat.
    Event: App\Events\PrivateMessageEvent
    CHANNEL private-private-chat.
    

    Notes:

    I have spent more than 10 hours and tried everything I could, but no luck.

    Thanks

  • Parth Vora
    Parth Vora about 7 years
    good spot, but it was just a typo in writing. Issue is something else
  • dparoli
    dparoli about 7 years
    writing in SO or in your code? because the laravel-echo-server output missed also the recieverId. it shoul be Channel: private-private-chat.1 for example
  • Parth Vora
    Parth Vora about 7 years
    On SO. Corrected now.