私人频道无法与 Laravel echo 服务器一起使用

Par*_*ora 3 websocket socket.io laravel laravel-echo laravel-5.4

我在控制台上收到此 JS 错误:

app.js:167 Uncaught ReferenceError:receiverId 未定义

这是我的完整代码:

私人聊天控制器:

event(new PrivateMessageEvent($chat, $receiverId));
Run Code Online (Sandbox Code Playgroud)

私信活动:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
});
Run Code Online (Sandbox Code Playgroud)

频道.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;
});
Run Code Online (Sandbox Code Playgroud)

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": ""
}
Run Code Online (Sandbox Code Playgroud)

在后台队列中:worklaravel-echo-server已经在运行

触发该事件后,我在 laravel-echo-server 控制台上收到此消息:

Channel: private-private-chat.
Event: App\Events\PrivateMessageEvent
CHANNEL private-private-chat.
Run Code Online (Sandbox Code Playgroud)

笔记:

我花了10多个小时,尝试了所有能做的事情,但没有成功。

谢谢

Mar*_*ton 5

您可以设置REDIS_PREFIXNULL删除前缀,否则如果它有值,则必须keyPrefix在回显服务器配置中进行设置。

如果REDIS_PREFIX= NULL 则不添加keyPrefix


重要的提醒

使用时broadcastAs(),调用calllisten('')必须以DOT开头

目前keyPrefix使用时的行为未知,如果您使用前缀设置,请评论 DOT 要求的结果。

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

public function broadcastAs()
{
    return 'server.created';
}
Run Code Online (Sandbox Code Playgroud)
.listen('.server.created', function (e) {
    ....
});
Run Code Online (Sandbox Code Playgroud)

我会自己检查 DOT + PREFIX 组合,但我觉得如果我再继续使用 Laravel Echo,我会心脏病发作。


如果不使用broadcastAs(),则命名将回退到事件类名称,在这种情况下,没有注入 DOT 前缀,请参阅下面的设置:

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"
        }
}
Run Code Online (Sandbox Code Playgroud)

/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);
  }

}

Run Code Online (Sandbox Code Playgroud)

触发事件(PHP)


use App\Events\MyExample

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

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

Run Code Online (Sandbox Code Playgroud)

监听事件(JavaScript)

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

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

})
Run Code Online (Sandbox Code Playgroud)