Private channel not working with Laravel echo server

旧街凉风 提交于 2020-04-06 04:07:49

问题


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'm successfully able to listen to the public channel. The only issue with the private channel.

  • Using latest Laravel version i.e 5.4

  • I have done all the things as per the official docs:

    https://laravel.com/docs/master/broadcasting

    https://github.com/tlaverdure/laravel-echo-server

  • I have also raised issue on github repo:

    https://github.com/tlaverdure/laravel-echo-server/issues/158

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

Thanks


回答1:


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.




回答2:


Try instead of event(new PrivateMessageEvent($chat, $receiverId)); this

App\Events\PrivateMessageEvent::dispatch($chat, $receiverId);



回答3:


There are a few things you need to do.

1) Remove all 'private-' from the beginning of your channel names. These get handled behind the scenes by the various libraries (eg socket.io/laravel-echo). If you look at any debug output you will see 'private-' prepended to the front of the channel names but you DO NOT need to add these.

2) If you're using redis then make sure the REDIS_PREFIX is set to an empty string in your .env file. By default it's set to something like 'laravel_database' and this messes up the channel names.

REDIS_PREFIX=

3) Make sure you've got your laravel-echo server running (and redis/pusher). Also you need to make sure you have the queue worker running. In my case, as i;m running redis, i had to run:

php artisan queue:work redis



回答4:


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 keyPefix.


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.


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)

})


来源:https://stackoverflow.com/questions/43317020/private-channel-not-working-with-laravel-echo-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!