事件监听器正在监听,但不会从事件中触发

时间:2020-05-19 21:10:10

标签: php node.js laravel vue.js laravel-echo

您好,我目前正在与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'
});

有人可以给我提示我可以开始调试的地方,也许是我做错了吗? 当缺少有关我的代码的信息时,请告诉我。

1 个答案:

答案 0 :(得分:0)

我找到了问题的原因。如您在redis监视中所见,通道名称带有前缀。 我设置 REDIS_PREFIX =
在.env中删除此前缀。现在我从听众那里得到了答案。