2

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

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

这是我的完整代码:

私人聊天控制器:

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

私人消息事件:

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

引导程序.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);
});

频道.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": ""
}

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

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

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

笔记:

我已经花了 10 多个小时,尽我所能,但没有运气。

谢谢

4

4 回答 4

4

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

如果REDIS_PREFIX= NULL 则不要添加keyPrefix.


重要通知

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

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

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

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

我会检查自己的 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"
        }
}

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

}

触发事件 (PHP)


use App\Events\MyExample

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

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

监听事件 (JavaScript)

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

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

})
于 2020-04-02T13:19:07.530 回答
1

尝试更改此行:

$this->$receiverId = $receiverId;

到这一行:

$this->receiverId = $receiverId;

在您的 PrivateMessageEvent __construct()

更新:

尝试使用固定的频道 ID,如下所示:

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

我建议你也使用出席频道,也是私人的,但有更多的功能,即:

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

如果您使用像您使用的动态频道号,即:

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

你必须receiverId在 javascript 中给出一个值,这个声明是一个通用的房间监听器,但应该定义 receiverId,${receiverId} 是一个字符串插值。

您可以在引入 app.js 之前在模板中定义 receiverId,例如,使用刀片语法:

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

另一个想法:我想明确一点,在上面的所有代码中,receiverId 表示客户端想要加入的聊天/房间的 ID,而不是接收用户的 ID。

于 2017-04-10T08:14:51.103 回答
0

试试event(new PrivateMessageEvent($chat, $receiverId)); 这个

App\Events\PrivateMessageEvent::dispatch($chat, $receiverId);
于 2018-11-06T10:02:38.427 回答
0

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
于 2020-03-23T03:55:35.253 回答