Laravel-echo-server 和 socket.io on homestead 得到 TypeError:无法读取属性 'socketId' 和 'presenceChannel'



我正在尝试使用laravel 5.4,laravel-echo,redis和socket-io创建实时聊天应用。

请在下面检查我的代码,然后我的问题

聊天转换事件:

class ChatConversation implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $message;
    public $user;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Chat $message, User $user)
    {
        $this->message = message;
        //Người gửi
        $this->user = $user
    }
    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PresenceChannel('chatroom');
    }
}

我的web.php:

Route::post('/privatechat/{id}/{receiver_id}', function(){
        $user = Auth::user();
        $room_id = request()->segment(5);
        $rec = request()->segment(6);
        $message = Chat::create([
            'chat_room'     =>  $room_id,
            'message'       =>  request()->get('message'),
            'sender_id'     =>  $user->id,
            'receiver_id'   =>  $rec
        ]);
        broadcast(new ChatConversation($message, $user));
        return ['status' => 'OK'];
    })->middleware('auth');

我的聊天vue设置:

const app = new Vue({
                el: '#app',
                data: {
                    messages: [],
                    sendClass: 'chat-send'
                    //Điều kiện
                },
                methods: {
                    addMessage(message) {
                        this.messages.push(message);
                        axios.post(url_post, message);
                        /*.then(function (response) {
                            //swal('Tuyệt vời! Work like a charm!');
                            console.log(response);
                        })
                        .catch(function (error) {
                            console.log(error);
                        });*/
                    }
                },
                created() {
                    var u = url;
                    axios.get(u).then(response => {
                        //console.log(response);
                        this.messages = response.data;
                    });
                    /*Echo.join('chatroom')
                    .here()
                    .joining()
                    .leaving()
                    .listen('ChatConversation', (e) => {
                        console.log(e);
                    })*/
                    Echo.join('chatroom')
                        .listen('ChatConversation', (e) => {
                            console.log(e);
                        })
                }
            });

我的bootstrap.js

import Echo from "laravel-echo"
window.Echo = new Echo({
    broadcaster:  '../socket.io-client/dist/socket.io',
    host: window.location.hostname + ':6001'
});

我的laravel-echo-server.json

"devMode": true,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"sslCertPath": "",
"sslKeyPath": ""
  1. 我的第一个问题是我使用此脚本访问客户端库时:

    src ="//{{request :: gethost((}}:6001/socket.io/socket.io.js

我得到此错误获取http://hgc.develop:6001/socket.io/socket.io.js net :: err_connection_refuse因此,我必须从Bower下载插座,然后将上面的线更改为

<script src="{{ asset('js/socket.io-client/dist/socket.io.js') }}"></script>
  1. 我的第二个问题是,当我进入聊天应用程序页面时,控制台向我展示了这些错误:

    app.js:35246 TypeError:无法读取未定义的属性'PresenceChannel'

    app.js:15520 Underfult(在承诺中(TypeError:无法读取未定义的属性

再一次,我关注本教程以创建我的聊天应用程序:https://www.youtube.com/watch?v=8atfmhg3v1q,但我使用redis and socket.io代替pusher

我的代码中有什么问题?我该如何处理这些问题?

我终于设法弄清楚了。我浏览了JS文件,并设法将其固定为以下事实:如果Laravel Channels.php签到可以收听通道的 try catch部分,则实际上不会丢弃错误。实例应该。

在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,则代码应该停止尝试连接到存在或私人频道。

无论如何,要实际返回用户,请确保您使用Laravel的Auth System已记录。如果您不使用它,则可能必须进行一些工作才能使其工作。如果您不使用它,那么Laravel中的此功能将引发403错误,因为它找不到您登录。

我必须过度编写将密码哈希算法检查到使用提供商的自定义算法的功能,这样我就不会弄乱laravel core,并使用户模型扩展了类Laravel正在寻找的类。

然后在您的channels.php文件中,只需确保您正在做什么检查您实际上是在从验证中返回回调函数中的$用户。这样的东西:

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

这是一个超级简单的私人/影响渠道,但是登录用户并返回$用户,这不会丢弃此错误。

另外,请确保您在回声实例中调用socket.io:

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

最新更新