Я пытаюсь создать SPA с vuejs во внешнем интерфейсе и laravel на внутреннем сервере и сервером nodejs для обслуживания соединений socket.io.Я могу транслировать события с общедоступных и частных каналов laravel на socket.io через redis и передавать их на клиентскую сторону.Ранее, когда я создал приложение с laravel и vuejs, которое поставляется с laravel, мне удалось реализовать чат-комнату, используя laravel echo и laravel echo server, но в 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';
}
}
routs / channel.php
<?php
use Illuminate\Support\Facades\Auth;
Broadcast::channel('Chat', function() {
if(Auth::check())
return Auth::user();
});
Thisэто сервер 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');
});