WebSocket — это протокол, обеспечивающий двустороннюю связь между клиентом и сервером в реальном времени. В отличие от традиционного HTTP, WebSocket позволяет открывать постоянное соединение, по которому данные могут передаваться мгновенно без повторных запросов. Во Vue.js WebSocket широко используется для создания чатов, онлайн-игр, мониторинга данных и любых приложений с динамическим обновлением интерфейса.
Для работы с WebSocket создается экземпляр объекта
WebSocket с указанием URL сервера:
const socket = new WebSocket('ws://localhost:8080');
Основные события WebSocket:
open — соединение установлено;message — получено сообщение от сервера;error — произошла ошибка;close — соединение закрыто.Пример подключения с обработкой событий:
socket.addEventListener('open', () => {
console.log('Соединение открыто');
});
socket.addEventListener('message', (event) => {
console.log('Получено сообщение:', event.data);
});
socket.addEventListener('error', (error) => {
console.error('Ошибка WebSocket:', error);
});
socket.addEventListener('close', () => {
console.log('Соединение закрыто');
});
WebSocket удобно интегрировать через жизненный цикл компонентов.
Обычно соединение открывается в mounted, а закрывается в
beforeUnmount:
<template>
<div>
<ul>
<li v-for="msg in messages" :key="msg.id">{{ msg.text }}</li>
</ul>
<input v-model="newMessage" @keyup.enter="sendMessage" placeholder="Введите сообщение">
</div>
</template>
<script>
export default {
data() {
return {
socket: null,
messages: [],
newMessage: ''
};
},
mounted() {
this.socket = new WebSocket('ws://localhost:8080');
this.socket.addEventListener('message', (event) => {
const message = JSON.parse(event.data);
this.messages.push(message);
});
},
beforeUnmount() {
if (this.socket) {
this.socket.close();
}
},
methods: {
sendMessage() {
if (this.newMessage.trim() !== '') {
const message = { text: this.newMessage };
this.socket.send(JSON.stringify(message));
this.newMessage = '';
}
}
}
};
</script>
Ключевые моменты:
data,
чтобы Vue автоматически обновлял интерфейс.beforeUnmount обязательно, чтобы
избежать утечек памяти.Для крупных проектов часто применяются плагины, такие как
vue-native-websocket, которые упрощают интеграцию:
import Vue from 'vue';
import VueNativeSock from 'vue-native-websocket';
Vue.use(VueNativeSock, 'ws://localhost:8080', {
format: 'json',
reconnection: true,
reconnectionAttempts: 5,
reconnectionDelay: 3000
});
После подключения события можно обрабатывать через глобальные методы:
this.$socket.sendObj({ type: 'greet', payload: 'Привет!' });
Для управления состоянием WebSocket-соединений в больших приложениях удобно использовать Vuex или Pinia:
export const useChatStore = defineStore('chat', {
state: () => ({
messages: [],
socket: null
}),
actions: {
connect(url) {
this.socket = new WebSocket(url);
this.socket.addEventListener('message', (event) => {
this.messages.push(JSON.parse(event.data));
});
},
send(message) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(message));
}
},
disconnect() {
if (this.socket) {
this.socket.close();
this.socket = null;
}
}
}
});
Такое решение обеспечивает централизованное управление WebSocket-соединением и упрощает повторное использование в разных компонентах.
WebSocket соединение может быть неожиданно разорвано. Для повышения надежности нужно реализовать автоматическое переподключение:
function createWebSocket(url, onMessage) {
let socket = new WebSocket(url);
socket.addEventListener('open', () => console.log('Connected'));
socket.addEventListener('message', (event) => onMessage(JSON.parse(event.data)));
socket.addEventListener('close', () => {
console.log('Disconnected, reconnecting...');
setTimeout(() => createWebSocket(url, onMessage), 3000);
});
socket.addEventListener('error', (err) => console.error('WebSocket error', err));
return socket;
}
Использование такой функции гарантирует, что соединение восстанавливается автоматически при сбоях.
ArrayBuffer) для больших объемов информации.readyState перед отправкой сообщений.WebSocket можно удобно интегрировать через ref и
onMounted/onUnmounted:
import { ref, onMounted, onUnmounted } from 'vue';
export function useWebSocket(url) {
const socket = ref(null);
const messages = ref([]);
onMounted(() => {
socket.value = new WebSocket(url);
socket.value.addEventListener('message', (event) => {
messages.value.push(JSON.parse(event.data));
});
});
onUnmounted(() => {
if (socket.value) socket.value.close();
});
const send = (msg) => {
if (socket.value && socket.value.readyState === WebSocket.OPEN) {
socket.value.send(JSON.stringify(msg));
}
};
return { messages, send };
}
Такой подход делает WebSocket реактивным и легко интегрируемым в любой компонент Vue.
Эта методика обеспечивает гибкое управление соединениями, стабильную работу приложения в реальном времени и масштабируемую архитектуру для сложных Vue-проектов.