您好,我目前正在与Laravel学习Vue.js,并尝试开发团队聊天。 由于财务原因,我使用redis而不是pusher并使用了它 laravel echo server用于回显服务器。
选择小组后,群聊会将用户与私人频道联系起来。之后,它将加载消息并在前端显示它们。发送消息时,控制器操作将成功执行,并且消息将存储在数据库中。但是,用户和其他团队成员必须重新单击团队名称,然后重新加载messageList才能获取最新消息,尽管该事件是在回显服务器上触发的,并且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服务器中得到的:
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'
});
有人可以给我提示我可以开始调试的地方,也许是我做错了吗? 当缺少有关我的代码的信息时,请告诉我。
答案 0 :(得分:0)
我找到了问题的原因。如您在redis监视中所见,通道名称带有前缀。
我设置
REDIS_PREFIX =
在.env中删除此前缀。现在我从听众那里得到了答案。