【问题标题】:Laravel-echo cannot listen to private and presence channelsLaravel-echo 无法收听私人和在线频道
【发布时间】:2020-02-13 12:41:47
【问题描述】:

我正在使用 laravel-websockets 包与 vuejs 和 laravel-echo 来创建一个实时聊天应用程序。一切正常,但私人和在线通道在前端不起作用(后端正常),我在控制台中没有错误。

我正在使用 laravel 5.8 并使用 artisan serve 运行它。当我将私人频道更改为公共频道时,它工作正常。

// in bootstrap.js

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: '*********',
    cluster: 'ap2',
    'wsHost': window.location.hostname,
    'wsPort': 6001,
    disableStats: true
});

// in private vue component

Echo.private('privatechat.'+this.user.id)
   .listen('PrivateMessageSent',(e)=>{
       console.log('private message');      
    });

})
// in PrivateMessageSent.php

namespace App\Events;

use App\Http\Models\Chat;
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;

class PrivateMessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Chat $message)
    {
        $this->message = $message;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('privatechat.'.$this->message->receiver_id);
    }
}

//在channels.php中

Broadcast::channel('privatechat.{receiverid}', function($user,$receiverid) {
    return auth()->check();
});

【问题讨论】:

  • PrivateMessageSent 是一个事件类吗?请编辑问题并添加它
  • 我添加它。记得我登录了 websocket 面板,但它在前面不起作用
  • 我更新了答案

标签: php laravel vue.js laravel-echo


【解决方案1】:

您的日志中应该有此错误

Symfony\Component\Debug\Exception\FatalThrowableError 传递给 App\Events\PrivateMessageSent::__construct() 的参数 1 必须是 App\Http\Models\Chat 的实例,给定 App\Models\Chat 的实例

因为您可能在分派事件时传递了模型 App\Models\Chat 的实例,但在事件类中使用了 App\Http\Models\Chat

导入正确的类

// in PrivateMessageSent.php

namespace App\Events;

use App\Models\Chat; // <--- HERE
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;

class PrivateMessageSent implements ShouldBroadcast
{

另外,删除wsHost 参数以便能够连接,然后确保使用经过身份验证的用户ID 广播私人频道

这对我有用

bootstrap.js

import Echo from 'laravel-echo'

window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: '*********',
    cluster: 'eu',
    'wsPort': 6001,
    disableStats: true
});

调度事件示例

use App\Events\PrivateMessageSent;
use App\Models\Chat;

Route::get('/', function () {
    $message = Chat::create([
        'receiver_id' => auth()->id()
    ]);
    event(new PrivateMessageSent($message));
    return view('welcome');
});

还有一个像这样的 Vue 组件监听器

<template>
    <div></div>
</template>

<script>
export default {
    props: {
        user: {
            type: Object,
            required: true
        }
    },
    mounted() {
        Echo.private(`privatechat.${this.user.id}`).listen(
            "PrivateMessageSent",
            e => {
                console.log("private message");
            }
        );
    }
};
</script>

不要忘记将用户对象作为 prop 传递或使用 ajax 获取它

<example-component :user="{{ auth()->user() }}"></example-component>

Result

希望这会有所帮助

【讨论】:

    猜你喜欢
    • 2020-01-15
    • 2019-11-05
    • 2017-05-12
    • 2020-12-05
    • 2020-07-28
    • 2017-11-27
    • 2019-02-08
    • 2020-11-22
    • 1970-01-01
    相关资源
    最近更新 更多