事件侦听器正在侦听但不会被事件触发
Event listener is listening but doesn't get triggered from event
您好,我目前正在学习 Vue.js 和 Laravel,并尝试开发团队聊天。
由于经济原因,我使用了 redis 而不是 pusher 并使用了这个
laravel echo server 用于回显服务器。
只要您 select 一个团队,群聊就会将用户与私人频道联系起来。之后它加载消息并在前端显示它们。当您发送消息时,控制器操作成功执行并且消息存储在数据库中。然而,用户和其他团队成员必须重新单击团队名称并因此重新加载消息列表以获取最新消息,尽管事件在回显服务器上被触发并且 redis 接收到消息。
这是当有人选择团队聊天并发送消息时我从回显服务器得到的:
[10:20:41 PM] - gK5b68mvO1goLE4nAAAI authenticated for: private-messages.11
[10:20:41 PM] - gK5b68mvO1goLE4nAAAI joined channel: private-messages.11
Channel: clash_finder_database_private-messages.11
Event: App\Events\NewMessage
这是我从监控redis-server得到的:
1589921588.805758 [0 127.0.0.1:37594] "PUBLISH" "clash_finder_database_private-messages.11" "
{\"event\":\"App\\Events\\NewMessage\",\"data\":{\"message\":
{\"id\":9,\"message\":\"test\",\"team_id\":11,\"user_id\":3,\"created_at\":\"2020-05-19
20:53:08\",\"updated_at\":\"2020-05-19 20:53:08\"},\"socket\":null},\"socket\":null}"
我的 NewMessage 事件如下所示:
namespace App\Events;
use App\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class NewMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*
* @param Message $message
*/
public function __construct(Message $message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('messages.' . $this->message->team_id);
}
}
发送消息后将执行此控制器操作:
public function send(Request $request) {
$message = Message::create([
'team_id' => $request->team_id,
'user_id' => $request->user_id,
'message' => $request->text
]);
broadcast(new NewMessage($message));
return response()->json($message);
}
这是我的vue组件ChatApp.vue:
<template>
<div class="chat-container row">
<i class="far fa-comments fa-3x"></i>
<div id="chat-app" class="chat-app">
<div class="row mx-0 h-100 overflow-hidden">
<TeamList :teams="teamList" @selected="startConversationWith"/>
<Conversation :selectedTeam="selectedTeam" :messages="messages"
:user="user"/>
</div>
</div>
</div>
</template>
<script>
import MessageList from './MessageList';
import TeamList from './TeamList';
import Conversation from './Conversation';
import MessageTextBox from './MessageTextBox';
export default {
props: {
user: {
type: Object,
required: true
}
},
data() {
return {
messages: [],
teamList: [],
selectedTeam: null
}
},
mounted() {
axios.get('/teams')
.then((response) => {
this.teamList = response.data;
});
},
methods: {
startConversationWith(team) {
axios.get('/conversation/' + team.id)
.then((response) => {
this.messages = response.data;
this.selectedTeam = team;
});
if (team.id != null) {
if (this.selectedTeam == null) {
console.log("outside listener");
Echo.private('messages.' + team.id)
.listen('NewMessage', (e) => {
console.log("inside listener");
this.handleIncoming(e);
});
} else if(this.selectedTeam.id !== team.id) {
console.log("outside listener");
Echo.private('messages.' + team.id)
.listen('NewMessage', (e) => {
console.log("inside listener");
this.handleIncoming(e);
});
}
}
},
saveNewMessage(message) {
this.messages.push(message.message);
},
handleIncoming(message) {
this.saveNewMessage(message);
return;
}
},
components: {TeamList, MessageList, MessageTextBox, Conversation}
}
</script>
我调试了侦听器并注意到它被执行了,因为我的 console.log 就在执行之前,但是 listen() 中的 console.log 没有得到输出。
bootstrap.js:
import Echo from 'laravel-echo'
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
谁能给我一个提示,我可以从哪里开始调试,也许我做错了什么?
如果缺少有关我的代码的信息,请告诉我。
我找到问题的原因了。在redis监控上可以看到,通道名是有前缀的。
我设置
REDIS_PREFIX=
在 .env 中删除此前缀。现在我从听众那里得到了答案。
您好,我目前正在学习 Vue.js 和 Laravel,并尝试开发团队聊天。 由于经济原因,我使用了 redis 而不是 pusher 并使用了这个 laravel echo server 用于回显服务器。
只要您 select 一个团队,群聊就会将用户与私人频道联系起来。之后它加载消息并在前端显示它们。当您发送消息时,控制器操作成功执行并且消息存储在数据库中。然而,用户和其他团队成员必须重新单击团队名称并因此重新加载消息列表以获取最新消息,尽管事件在回显服务器上被触发并且 redis 接收到消息。
这是当有人选择团队聊天并发送消息时我从回显服务器得到的:
[10:20:41 PM] - gK5b68mvO1goLE4nAAAI authenticated for: private-messages.11
[10:20:41 PM] - gK5b68mvO1goLE4nAAAI joined channel: private-messages.11
Channel: clash_finder_database_private-messages.11
Event: App\Events\NewMessage
这是我从监控redis-server得到的:
1589921588.805758 [0 127.0.0.1:37594] "PUBLISH" "clash_finder_database_private-messages.11" "
{\"event\":\"App\\Events\\NewMessage\",\"data\":{\"message\":
{\"id\":9,\"message\":\"test\",\"team_id\":11,\"user_id\":3,\"created_at\":\"2020-05-19
20:53:08\",\"updated_at\":\"2020-05-19 20:53:08\"},\"socket\":null},\"socket\":null}"
我的 NewMessage 事件如下所示:
namespace App\Events;
use App\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class NewMessage implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*
* @param Message $message
*/
public function __construct(Message $message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('messages.' . $this->message->team_id);
}
}
发送消息后将执行此控制器操作:
public function send(Request $request) {
$message = Message::create([
'team_id' => $request->team_id,
'user_id' => $request->user_id,
'message' => $request->text
]);
broadcast(new NewMessage($message));
return response()->json($message);
}
这是我的vue组件ChatApp.vue:
<template>
<div class="chat-container row">
<i class="far fa-comments fa-3x"></i>
<div id="chat-app" class="chat-app">
<div class="row mx-0 h-100 overflow-hidden">
<TeamList :teams="teamList" @selected="startConversationWith"/>
<Conversation :selectedTeam="selectedTeam" :messages="messages"
:user="user"/>
</div>
</div>
</div>
</template>
<script>
import MessageList from './MessageList';
import TeamList from './TeamList';
import Conversation from './Conversation';
import MessageTextBox from './MessageTextBox';
export default {
props: {
user: {
type: Object,
required: true
}
},
data() {
return {
messages: [],
teamList: [],
selectedTeam: null
}
},
mounted() {
axios.get('/teams')
.then((response) => {
this.teamList = response.data;
});
},
methods: {
startConversationWith(team) {
axios.get('/conversation/' + team.id)
.then((response) => {
this.messages = response.data;
this.selectedTeam = team;
});
if (team.id != null) {
if (this.selectedTeam == null) {
console.log("outside listener");
Echo.private('messages.' + team.id)
.listen('NewMessage', (e) => {
console.log("inside listener");
this.handleIncoming(e);
});
} else if(this.selectedTeam.id !== team.id) {
console.log("outside listener");
Echo.private('messages.' + team.id)
.listen('NewMessage', (e) => {
console.log("inside listener");
this.handleIncoming(e);
});
}
}
},
saveNewMessage(message) {
this.messages.push(message.message);
},
handleIncoming(message) {
this.saveNewMessage(message);
return;
}
},
components: {TeamList, MessageList, MessageTextBox, Conversation}
}
</script>
我调试了侦听器并注意到它被执行了,因为我的 console.log 就在执行之前,但是 listen() 中的 console.log 没有得到输出。
bootstrap.js:
import Echo from 'laravel-echo'
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
谁能给我一个提示,我可以从哪里开始调试,也许我做错了什么? 如果缺少有关我的代码的信息,请告诉我。
我找到问题的原因了。在redis监控上可以看到,通道名是有前缀的。
我设置
REDIS_PREFIX=
在 .env 中删除此前缀。现在我从听众那里得到了答案。