Воспроизведение очереди при восстановлении сети

Workbox предоставляет мощные инструменты для организации оффлайн-режима и управления запросами к серверу, особенно в ситуациях, когда сеть нестабильна. Одной из ключевых возможностей является возможность отложенного выполнения запросов и их автоматическая отправка после восстановления соединения.

Workbox Background Sync

Для реализации воспроизведения очереди используется модуль Background Sync. Он позволяет сохранять сетевые запросы в локальном хранилище, если сеть недоступна, и автоматически повторять их при восстановлении соединения. Основной класс для работы — workbox.backgroundSync.Queue.

Пример создания очереди:

import { Queue } from 'workbox-background-sync';

const queue = new Queue('myQueue', {
  maxRetentionTime: 24 * 60 // 24 часа в минутах
});
  • myQueue — уникальное имя очереди.
  • maxRetentionTime — время хранения запросов в локальном хранилище, после которого они удаляются, если не были отправлены.

Перехват и добавление запросов в очередь

Для работы с Background Sync обычно используется Service Worker с fetch-перехватом. При недоступной сети запрос добавляется в очередь:

self.addEventListener('fetch', (event) => {
  if (event.request.method === 'POST') {
    event.respondWith(
      fetch(event.request.clone()).catch((err) => {
        return queue.pushRequest({ request: event.request.clone() })
          .then(() => new Response(null, { status: 200 }));
      })
    );
  }
});

Ключевые моменты:

  • Используется request.clone(), чтобы создать копию запроса, так как объект Request является одноразовым.
  • Метод pushRequest помещает запрос в очередь для последующей отправки.
  • После добавления в очередь возвращается успешный ответ, чтобы клиент продолжил работу без ошибок.

Настройка повторной отправки

Workbox автоматически повторяет отправку запросов при восстановлении сети. Дополнительно можно подписаться на события очереди для логирования или изменения поведения:

queue.on('sync', async ({ queue }) => {
  let entry;
  while ((entry = await queue.shiftRequest())) {
    try {
      await fetch(entry.request);
    } catch (error) {
      await queue.unshiftRequest(entry); // вернуть запрос в начало очереди
    }
  }
});
  • Событие sync срабатывает, когда сеть снова доступна.
  • shiftRequest() извлекает запрос из очереди.
  • При неудачной отправке запрос можно вернуть обратно с помощью unshiftRequest().

Интеграция с маршрутизацией Workbox

Часто Background Sync комбинируют с Workbox Routing, чтобы автоматически обрабатывать определённые маршруты:

import { registerRoute } from 'workbox-routing';
import { NetworkOnly } from 'workbox-strategies';

registerRoute(
  ({ url, request }) => url.pathname.startsWith('/api/') && request.method === 'POST',
  new NetworkOnly({
    plugins: [queue]
  }),
  'POST'
);
  • NetworkOnly стратегия используется для отправки запроса напрямую на сервер.
  • Плагин очереди перехватывает неудачные запросы и добавляет их в очередь для повторной отправки.
  • Удобно использовать для REST API или любых POST-запросов, где важно сохранить данные при оффлайне.

Работа с кастомными стратегиями и плагинами

Queue можно использовать вместе с любыми стратегиями Workbox через плагины, создавая более гибкую обработку ошибок и повторную отправку:

import { Plugin } from 'workbox-core';

const queuePlugin = {
  fetchDidFail: async ({ request }) => {
    await queue.pushRequest({ request });
  }
};

registerRoute(
  '/submit-form',
  new NetworkOnly({ plugins: [queuePlugin] }),
  'POST'
);
  • fetchDidFail срабатывает при любой сетевой ошибке.
  • Запрос автоматически сохраняется в очередь.

Мониторинг и очистка очереди

Для контроля состояния очереди можно использовать методы:

  • queue.getAll() — получить все запросы в очереди.
  • queue.delete() — удалить все запросы.
  • queue.shiftRequest() / queue.unshiftRequest() — выборочно управлять отправкой запросов.

Это позволяет создавать кастомные механизмы уведомления пользователей о состоянии оффлайн-запросов или управлять их приоритетами.

Ограничения и рекомендации

  • Queue сохраняет только объекты Request и Response, поэтому файлы больших размеров лучше отправлять напрямую с прогресс-отслеживанием.
  • Для критически важных данных рекомендуется реализовать резервное хранение в IndexedDB перед добавлением в очередь.
  • Максимальное время хранения (maxRetentionTime) следует настраивать исходя из сценария использования, чтобы не перегружать локальное хранилище.

Workbox Background Sync позволяет построить устойчивые к перебоям сети приложения с надежным воспроизведением запросов. Правильная конфигурация очередей и интеграция с маршрутизацией обеспечивают стабильность взаимодействия с сервером даже при частых оффлайн-ситуациях.