Не работает websocket в связке Vuejs+Laravel 11
Недавно начала изучать веб сокеты и все, что к нему прилагается в Laravel 11. Бэкенд реализовал собственно на ларе, добавил нужный эвент, обновил конфигурацию pusher и тд , фронтенд отдельным проектом на vueJs, где попросил ChatGPT накидать простой компонент экран, на котором бы выводились новые записи из бэкенда и сообщения в консоль, добавленные через postman.Соединение с вебсокетом на фронте есть, но новые сообщения никак не транслируются на клиент.
Ниже код на Laravel
Сам эвент
<?php
namespace App\Events;
use App\Models\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*/
public function __construct($message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
'chat',
];
}
public function broadcastWith()
{
return ['message' => $this->message];
}
}
Роут в routes/channels
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('chat', function () {
return true;
});
Сервис контейнер в котором вызывается эвент
namespace App\Services\Message;
use App\Models\Message;
use App\Events\MessageSent;
use Illuminate\Support\Facades\Log;
use App\Http\Requests\MessageValidation;
use App\Interfaces\Message\MessageServiceInterface;
class MessageService implements MessageServiceInterface
{
public function index(): object
{
$messages = Message::with(["user", "chat"])->get();
return $messages;
}
public function store(MessageValidation $req): Message
{
$validationData = $req->validated();
$newMessage = Message::create($validationData);
Log::info('Broadcasting message:', ['message' => $newMessage]);
broadcast(new MessageSent($newMessage))->toOthers();
return $newMessage;
}
public function show(Message $message): Message
{
return $message;
}
public function update(MessageValidation $req, Message $message): Message
{
$validationData = $req->validated();
$message->update($validationData);
return $message;
}
public function destroy(Message $message): void
{
$message->delete();
}
}
Vuejs компонента
<template>
<div>
<ul v-if="!isLoading">
<li v-for="message in messageStore.messages" :key="message.id">
<strong>{{ message.user.name }}</strong>: {{ message.message }}
<span class="date">({{ formatDate(message.created_at) }})</span>
</li>
</ul>
<p v-else>Загрузка...</p> <!-- Индикатор загрузки -->
</div>
</template>
<script>
import { onMounted, ref } from 'vue';
import { useMessageStore } from '../stores/messageStore';
import Echo from "laravel-echo";
import Pusher from "pusher-js";
export default {
setup() {
const messageStore = useMessageStore();
const isLoading = ref(true); // Переменная для отслеживания состояния загрузки
// Подключаемся к Pusher
window.Pusher = Pusher;
const echo = new Echo({
broadcaster: "pusher",
key: "5a0c13e00857a82a2bb6",
cluster: "eu",
forceTLS: true,
});
echo.connector.pusher.connection.bind('connected', () => {
console.log('Подключение к Pusher успешно!');
});
echo.connector.pusher.connection.bind('disconnected', () => {
console.log('Подключение к Pusher разорвано.');
});
echo.connector.pusher.connection.bind('error', (error) => {
console.error('Ошибка подключения к Pusher:', error);
});
echo.channel("chat")
.listen("MessageSent", (event) => {
console.log(event);
// messageStore.addMessage(event.message);
});
// Загружаем сообщения при монтировании
onMounted(async () => {
await messageStore.loadMessages(); // Загружаем сообщения при монтировании компонента
isLoading.value = false; // Устанавливаем состояние загрузки в false после загрузки
});
// Функция для форматирования даты
const formatDate = (dateString) => {
const options = { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' };
return new Date(dateString).toLocaleDateString(undefined, options);
};
return {
formatDate,
messageStore,
isLoading, // Возвращаем переменную состояния загрузки
};
},
};
</script>
Store
import { defineStore } from 'pinia';
const API_URL = 'http://127.0.0.1:8000/api/messages';
export const useMessageStore = defineStore('messageStore', {
state:()=>({
messages:[],
}),
getters:{},
actions:{
async loadMessages(){
try {
const response = await fetch(API_URL);
if (!response.ok) throw new Error('Failed to fetch messages');
const data = await response.json();
this.messages = data.messages; // Используйте .messages, если ваш ответ содержит его
} catch (error) {
console.error(error);
}
},
addMessage(message){
this.messages.push(message)
}
}
});
vue.config.js
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
host: '127.0.0.1', // Указываем хост
port: 8080, // Укажите порт, на котором работает ваш сервер\
proxy: {
'/api': {
target: 'http://127.0.0.1:8000', // Порт вашего Laravel приложения
changeOrigin: true,
},
},
},
})
Ответы (1 шт):
Смог решить эту ошибку добавив "." перед названием эвента в vuejs + очистив кэш в laravel
echo.channel("Chat")
.listen(".chat.message", e => {
console.log(e);
messageStore.addMessage(e);
});