Laravel Echo不会使用socket.io捕获事件

时间:2017-08-08 18:48:33

标签: php laravel socket.io laravel-echo socket.io-redis

我使用Redis和Socket.io来设置实时更新,但Laravel Echo没有捕获事件。

如果我使用io()的实例,它可以正常工作。这是我的vue应用程序中的代码,用于监听事件:

不会捕捉事件

window.Echo.channel('users')
    .listen('UserCreated', event => {
            console.log(event);
            this.all_users.push(event.user);
            this.filter_data();
    });

将抓住事件

window.socket = io(window.location.origin+':3000');
window.socket.on('users:App\\Events\\UserCreated', function(data){
    console.log(data);
    console.log('from socket');
    this.all_users.push(data.user);
    this.filter_data();
}.bind(this));

我的节点用于推送事件的代码。

var server = require('http').Server();

var io = require('socket.io')(server);

var Redis = require('ioredis');

var redis = new Redis();

redis.subscribe('users', function(error, count){
    console.log(error);
    console.log(count);
});

redis.on('message', function(channel, message){
    console.log(channel);
    message = JSON.parse(message);
    console.log(message);
    const emmitChannel = `${channel}:${message.event}`;
    console.log(emmitChannel);
    io.emit(emmitChannel, message.data);
});

server.listen(3000);

我的Laravel活动广播

<?php

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;


//Models
use App\User;

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

    public $user;

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

        $this->dontBroadcastToCurrentUser();
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return ['users'];
    }
}

我已经尝试更改事件传递给Laravel Echo的方式,因为默认情况下它会以users:App\Events\UserCreated的形式接收它们但我没有运气。

1 个答案:

答案 0 :(得分:0)

我终于设法解决了这个问题。我仔细查看了JS文件并设法将其归结为the code in this line如果Laravel channels.php检查谁可以收听某个频道而没有实际发生错误try catch部分这样的事实&#39 ; t应该返回用户模型实例。

Channels.php中的类似内容会抛出该错误:

Broadcast::channel('users', function ($user) {
    if($user->type == 'admin'){
         return $user;
    }else{
         return false;
    }
});

如果$user没有通过if检查,Laravel将返回false。由于它没有返回JSON而只是假,我认为它应该记录响应主体没有通过JSON.parse()函数,所以你可以在终端中看到它。像这样:

try {
     body = JSON.parse(response.body);
} catch (e) {
     Log.warning('Response body provided is not expected JSON. Response body provided ${response.body}');
     body = response.body;
}

这样我们就可以看出Laravel是否还没有返回用户模型实例。

因此,当您没有按预期获得用户模型实例时,没有用于将sockedId附加到代码的用户对象,因为它未定义。从来没有任何JSON来制作对象。

如果您没有获取用户实例而不是尝试附加套接字ID,我认为代码应该停止尝试连接到状态或私有通道。

无论如何,要真正返回用户,请确保您已登录using Laravel's Auth system.如果您没有使用它,则可能需要做一些工作才能使其正常工作。如果您没有使用它,请this function in Laravel will throw a 403 error because it can't find you to be logged in

我不得不将使用提供程序检查密码哈希算法的函数写入自定义算法,这样我就不会弄乱Laravel核心并使用户模型扩展Laravel正在寻找的类。

然后在你的channels.php文件中,确保检查你是否正在通过auth检查Broadcaster.php文件实际返回回调函数中的$ user。像这样:

Broadcast::channel('users', function ($user) {
     return $user;
});

这是一个超级简单的私人/在线频道,但有一个登录用户并返回$ user,这不会抛出此错误。

另外,请确保您在Echo实例中调用socket.io,如下所示:

window.Echo = new Echo({
    broadcaster:  'socket.io',
    host: window.location.origin + ':6001'
});