问题
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 addkeyPefix
.
Important Notice
When using
broadcastAs()
, the call tolisten('')
call must start with a DOTAt 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