如何将laravel状态通道与nodejs socket.io链接

时间:2018-10-16 00:17:49

标签: node.js laravel vue.js socket.io

我正在尝试使用前端的vuejs和后端的laravel以及nodejs服务器中的laravel创建SPA,以提供socket.io连接。 我可以通过redis将事件从laravel公共和私有渠道传播到socket.io,并将其发送到客户端。 以前,当我使用laravel附带的laravel和vuejs制作应用程序时,我设法使用laravel echo和laravel echo服务器实现了一个聊天室,但是在SPA中,我找不到实现此目的的方法。 Laravel Echo具有.here()。joining()。leaving()方法,可用于构建聊天室。但是我该如何用socket.io实现这个方法呢?

在客户端,我正在使用vue-socket.io。 这是vue组件,用于侦听来自socket.io服务器的事件。

<template>
    <div class="container products">
        <products></products>
    </div>
</template>

<script>

import Products from './products/Products.vue'

export default {

    created() {
        this.$http.post('auth/token', {
            xhrFields: {
                withCredentials: true
            }
        })
        .then(response => {
            this.$socket.emit('authenticate', {
                token: response.data.token
            });
        })
        .catch(error => {
            console.log(error.response)
        });
    },

    components: {
       'products':  Products
    },
    sockets: {
        message(msg) {
            console.log(msg)
        }
    }
}
</script>

<style>
    .products {margin-top:60px}
</style>

MessageSentEvent.php

<?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;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Support\Facades\Auth;

class MessageSentEvent implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;

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

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        if(Auth::check())
            return new PresenceChannel('Chat');
    }

    public function broadcastAs()
    {
        return 'message';
    }
}

routes / channels.php

<?php

use Illuminate\Support\Facades\Auth;

Broadcast::channel('Chat', function() {
    if(Auth::check())
        return Auth::user();
});

这是nodejs服务器 server.js

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
var socketioJwt = require('socketio-jwt');
require('dotenv').config({
    path: '../backend/.env'
});

// Accept connection and authorize token
io.on('connection', socketioJwt.authorize({
    secret: process.env.JWT_SECRET,
    timeout: 15000
}));

/* When authenticated, listen to events that come from laravel throug redis */
io.on('authenticated', function (socket) {

    console.log('a user connected');
    socket.emit('id', socket.decoded_token.sub);

    var redisClient = redis.createClient();
    redisClient.subscribe('presence-Chat');
    redisClient.on('message', (channel, message) => {
        console.log('channel: ' + channel + '\nmessage: ' + message);
        socket.emit('message', JSON.parse(message).data.message);
    });

    socket.on('logout', () => {
        redisClient.quit();
        console.log('a user quit');
    });
});

io.on('disconnect', function (){
    console.log('a user disconnected');
});

server.listen(3000, function() {
    console.log('listening on port 3000');
});

0 个答案:

没有答案