Композируемый модуль useWebSocket с переподключением
Обёртка над WebSocket в композируемом модуле, автоматическое переподключение с экспоненциальной задержкой и отслеживание состояния
«Композируемый модуль useWebSocket с переподключением» — бесплатный урок Vue Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.
Инкапсуляция WebSockets в компонуемой функции
Разрозненная обработка WebSocket в компонентах быстро становится неудобной. Компонуемая функция useWebSocket централизует состояние подключения, переподключение и обработку сообщений, а затем позволяет повторно использовать эту логику везде.
Мы создадим её поэтапно.
Отслеживание состояния через реактивную ссылку
Предоставьте состояние подключения в виде реактивного status ref, чтобы интерфейс мог показывать метки «Подключение», «Открыто» или «Закрыто».
import { ref } from "vue"
export function useWebSocket(url) {
const status = ref("CLOSED") // CONNECTING | OPEN | CLOSED
// ...
return { status }
}Функция подключения
Инкапсулируйте открытие сокета во внутренней функции connect, чтобы позже можно было снова вызвать её для переподключения. Обновляйте status при каждом событии жизненного цикла.
let ws
function connect() {
status.value = "CONNECTING"
ws = new WebSocket(url)
ws.onopen = () => { status.value = "OPEN" }
ws.onclose = () => { status.value = "CLOSED"; scheduleReconnect() }
}Переподключение с увеличивающейся задержкой
Мгновенные переподключения в тесном цикле создают чрезмерную нагрузку на сервер. Используйте экспоненциальное увеличение интервала: после каждой неудачной попытки ждите дольше, но не превышайте установленный предел.
let attempts = 0
function scheduleReconnect() {
attempts++
const delay = Math.min(1000 * 2 ** attempts, 30000)
setTimeout(connect, delay)
}Сброс задержки после успешного подключения
После успешного подключения сбросьте счетчик попыток, чтобы при следующем отключении задержка снова начиналась с минимального значения, а не сразу была большой.
ws.onopen = () => {
status.value = "OPEN"
attempts = 0
flushQueue()
}Очередь сообщений при отключении
Если пользователь отправляет сообщение, когда сокет отключен, его нельзя терять. Буферизуйте исходящие сообщения в очереди и отправляйте их все после открытия соединения.
const queue = []
function send(data) {
const payload = JSON.stringify(data)
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(payload)
} else {
queue.push(payload)
}
}Очистка очереди
После открытия сокета обработайте всё накопившееся. Извлекайте элементы с начала с помощью shift, чтобы сохранить порядок.
function flushQueue() {
while (queue.length && ws.readyState === WebSocket.OPEN) {
ws.send(queue.shift())
}
}Типизированные обработчики сообщений
Позвольте потребителям регистрировать обработчики для каждого type сообщения. Сохраняйте обратные вызовы в карте и при каждом входящем кадре выбирайте обработчик по типу сообщения.
const handlers = {}
function on(type, cb) { handlers[type] = cb }
// inside connect:
ws.onmessage = (e) => {
const msg = JSON.parse(e.data)
if (handlers[msg.type]) handlers[msg.type](msg.payload)
}Очистка в onUnmounted
Компонуемая функция управляет таймерами и сокетом. Останавливайте их при размонтировании использующего компонента, чтобы переподключение не продолжалось после исчезновения представления.
import { onUnmounted } from "vue"
let reconnectTimer
onUnmounted(() => {
clearTimeout(reconnectTimer)
if (ws) ws.close(1000, "component unmounted")
})Запрет переподключения после намеренного закрытия
Корректное закрытие (код 1000) во время собственной очистки НЕ должно запускать переподключение. Отслеживайте флаг intentional и не планируйте переподключение, если он установлен.
let intentional = false
function close() { intentional = true; ws.close(1000) }
ws.onclose = () => {
status.value = "CLOSED"
if (!intentional) scheduleReconnect()
}Полная структура компонуемой функции
Теперь всё собрано вместе: подключение при создании, предоставление status, send и on, постановка сообщений в очередь при отключении, переподключение с увеличением интервала и автоматическая очистка.
export function useWebSocket(url) {
const status = ref("CLOSED")
// connect, scheduleReconnect, send, on, flushQueue, cleanup...
connect()
return { status, send, on, close }
}
// usage:
// const { status, send, on } = useWebSocket("wss://...")Быстрая проверка
Проверьте, насколько хорошо Вы понимаете стратегию переподключения.
Итоги
Вы создали надежную компонуемую функцию useWebSocket:
- Реактивный
statusотражает состояния CONNECTING / OPEN / CLOSED для интерфейса. - Переподключайтесь с экспоненциальным увеличением интервала, ограничивайте задержку и сбрасывайте счетчик после успешного подключения.
- Ставьте исходящие сообщения в очередь при отключении и отправляйте их после открытия соединения.
- Передавайте входящие кадры обработчикам обратных вызовов для соответствующих типов.
- Очищайте таймеры и сокет в
onUnmounted, пропуская переподключение после намеренного закрытия.
Часто задаваемые вопросы
Урок «Композируемый модуль useWebSocket с переподключением» бесплатный?
Да — полный текст урока «Композируемый модуль useWebSocket с переподключением» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.
Чему я научусь в уроке «Композируемый модуль useWebSocket с переподключением»?
Обёртка над WebSocket в композируемом модуле, автоматическое переподключение с экспоненциальной задержкой и отслеживание состояния Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Vue Academy?
Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Композируемый модуль useWebSocket с переподключением»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Vue Academy?
Да. Каждый урок Vue Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы WebSocket в браузере
- Клиент Socket.io с Vue
- Создание компонента чата в реальном времени
- Композируемый модуль useWebSocket с переподключением