私人频道不适用于 Laravel 回显服务器
Posted
技术标签:
【中文标题】私人频道不适用于 Laravel 回显服务器【英文标题】:Private channel not working with Laravel echo server 【发布时间】:2017-09-05 03:13:30 【问题描述】:我在控制台上收到这个 JS 错误:
app.js:167 Uncaught ReferenceError: receiverId is not defined
这是我的完整代码:
私人聊天控制器:
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": ""
在后台 queue:work 和 laravel-echo-server 已经在运行
触发该事件后,我在 laravel-echo-server 控制台上收到此消息:
Channel: private-private-chat.
Event: App\Events\PrivateMessageEvent
CHANNEL private-private-chat.
注意事项:
我已成功收听公共频道。私人频道的唯一问题。
使用最新的 Laravel 版本,即 5.4
我已经按照官方文档做了所有的事情:
https://laravel.com/docs/master/broadcasting
https://github.com/tlaverdure/laravel-echo-server
我也在 github repo 上提出了问题:
https://github.com/tlaverdure/laravel-echo-server/issues/158
我已经花了 10 多个小时,尽我所能,但没有运气。
谢谢
【问题讨论】:
在触发事件之前,请执行dd($receiverId);
。它说$receiverId
是空的吗?
@jono20201,我已经检查了变量。它具有正确的值 - 不为空。
【参考方案1】:
您可以将REDIS_PREFIX
设置为NULL
以删除前缀,否则如果它有值,则必须在回显服务器配置中设置keyPrefix
。
如果
REDIS_PREFIX
= NULL 则不要添加keyPrefix
。
重要通知
使用
broadcastAs()
时,对listen('')
的调用必须以点开头此时使用
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)
)
【讨论】:
【参考方案2】:尝试改变这一行:
$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`)
你必须在javascript中给receiverId
一个值,这个声明是一个通用的房间监听器但是receiverId应该被定义,$receiverId是一个字符串插值。
你可以在引入app.js之前在模板中定义receiverId,例如使用刀片语法:
<script>
receiverId = $receiverId ;
</script>
另一个想法:我想明确一点,在上面的所有代码中,receiverId 代表客户想要加入的聊天/房间的 ID,而不是接收用户的 ID。
【讨论】:
好地方,但这只是写作中的一个错字。问题是别的东西 用 SO 或您的代码编写?因为 laravel-echo-server 输出也错过了recieverId。例如应该是Channel: private-private-chat.1
就这样。现已更正。【参考方案3】:
尝试代替event(new PrivateMessageEvent($chat, $receiverId));
这个
App\Events\PrivateMessageEvent::dispatch($chat, $receiverId);
【讨论】:
【参考方案4】:您需要做一些事情。
1) 删除频道名称开头的所有“private-”。这些由各种库(例如socket.io/laravel-echo)在幕后处理。如果您查看任何调试输出,您会看到通道名称前面附加了“private-”,但您不需要添加这些。
2) 如果您使用的是 redis,请确保在 .env 文件中将 REDIS_PREFIX 设置为空字符串。默认情况下,它设置为“laravel_database”之类的东西,这会弄乱频道名称。
REDIS_PREFIX=
3) 确保你的 laravel-echo 服务器正在运行(和 redis/pusher)。此外,您需要确保队列工作程序正在运行。就我而言,当我运行 redis 时,我必须运行:
php artisan queue:work redis
【讨论】:
以上是关于私人频道不适用于 Laravel 回显服务器的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Echo 私人频道和 Laravel echo 服务器 |雷迪斯
无法使用 Laravel echo server、redis 和 socket.io 验证 laravel 私人频道