0Pricing
Vue Academy · Урок

Композируемый модуль 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 — локальная установка не требуется.

Все уроки этого курса

  1. Основы WebSocket в браузере
  2. Клиент Socket.io с Vue
  3. Создание компонента чата в реальном времени
  4. Композируемый модуль useWebSocket с переподключением
← Назад к Vue Academy