我正在尝试使用前端的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');
});