هنگامی که داده ها را به یک وب سرور ارسال می کنید، گاهی اوقات درخواست ها با شکست مواجه می شوند. ممکن است به این دلیل باشد که کاربر اتصال خود را از دست داده است، یا ممکن است به دلیل از کار افتادن سرور باشد. در هر صورت اغلب می خواهید درخواست ها را بعداً دوباره ارسال کنید.
BackgroundSync API جدید یک راه حل ایده آل برای این مشکل است. هنگامی که یک سرویسدهنده تشخیص میدهد که درخواست شبکه ناموفق بوده است، میتواند برای دریافت یک رویداد sync ثبتنام کند، که وقتی مرورگر فکر میکند اتصال بازگشته است، تحویل داده میشود. توجه داشته باشید که رویداد همگامسازی را میتوان حتی در صورتی که کاربر برنامه را ترک کرده باشد ، تحویل داد، که آن را بسیار مؤثرتر از روش سنتی امتحان مجدد درخواستهای ناموفق میکند.
Workbox Background Sync برای سهولت استفاده از BackgroundSync API و ادغام استفاده از آن با سایر ماژول های Workbox طراحی شده است. همچنین یک استراتژی بازگشتی برای مرورگرهایی که هنوز BackgroundSync را پیاده سازی نکرده اند، پیاده سازی می کند.
مرورگرهایی که از BackgroundSync API پشتیبانی میکنند، بهطور خودکار درخواستهای ناموفق را از طرف شما در بازهای که توسط مرورگر مدیریت میشود، دوباره پخش میکنند، احتمالاً با استفاده از عقبنشینی نمایی بین تلاشهای مجدد. در مرورگرهایی که بهطور بومی از BackgroundSync API پشتیبانی نمیکنند، Workbox Background Sync بهطور خودکار هر زمان که سرویسگر شما راهاندازی میشود، دوباره پخش میکند.
استفاده پایه
سادهترین راه برای استفاده از همگامسازی پسزمینه، استفاده از Plugin است که بهطور خودکار درخواستهای ناموفق را در صف قرار میدهد و زمانی که رویدادهای sync آینده فعال میشوند، دوباره آنها را امتحان میکند.
import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
maxRetentionTime: 24 * 60, // Retry for max of 24 Hours (specified in minutes)
});
registerRoute(
/\/api\/.*\/*.json/,
new NetworkOnly({
plugins: [bgSyncPlugin],
}),
'POST'
);
BackgroundSyncPlugin به پاسخ تماس پلاگین fetchDidFail متصل میشود و fetchDidFail تنها در صورتی فراخوانی میشود که استثنایی وجود داشته باشد، به احتمال زیاد به دلیل نقص شبکه. این بدان معناست که اگر پاسخی با وضعیت خطای 4xx یا 5xx دریافت شود، درخواستها دوباره امتحان نمیشوند. اگر میخواهید همه درخواستهایی را که منجر به وضعیت 5xx میشوند دوباره امتحان کنید، میتوانید با افزودن یک افزونه fetchDidSucceed به استراتژی خود این کار را انجام دهید:
const statusPlugin = {
fetchDidSucceed: ({response}) => {
if (response.status >= 500) {
// Throwing anything here will trigger fetchDidFail.
throw new Error('Server error.');
}
// If it's not 5xx, use the response as-is.
return response;
},
};
// Add statusPlugin to the plugins array in your strategy.
استفاده پیشرفته
Workbox Background Sync همچنین یک کلاس Queue ارائه می دهد که می توانید آن را نمونه سازی کنید و درخواست های ناموفق را به آن اضافه کنید. درخواستهای ناموفق در IndexedDB ذخیره میشوند و زمانی که مرورگر فکر میکند اتصال بازیابی شده است (یعنی زمانی که رویداد همگامسازی را دریافت میکند) دوباره امتحان میشوند.
ایجاد صف
برای ایجاد صف همگامسازی پسزمینه Workbox، باید آن را با نام صف بسازید (که باید منحصر به فرد باشد):
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
نام صف به عنوان بخشی از نام تگ استفاده می شود که register() -ed توسط SyncManager جهانی دریافت می کند. همچنین به عنوان نام Object Store برای پایگاه داده IndexedDB استفاده می شود.
افزودن یک درخواست به صف
هنگامی که نمونه Queue خود را ایجاد کردید، می توانید درخواست های ناموفق را به آن اضافه کنید. شما درخواست ناموفق را با فراخوانی متد .pushRequest() اضافه می کنید. به عنوان مثال، کد زیر هر درخواستی را که با شکست مواجه می شود را می گیرد و آنها را به صف اضافه می کند:
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
self.addEventListener('fetch', event => {
// Add in your own criteria here to return early if this
// isn't a request that should use background sync.
if (event.request.method !== 'POST') {
return;
}
const bgSyncLogic = async () => {
try {
const response = await fetch(event.request.clone());
return response;
} catch (error) {
await queue.pushRequest({request: event.request});
return error;
}
};
event.respondWith(bgSyncLogic());
});
هنگامی که به صف اضافه می شود، درخواست به طور خودکار زمانی که سرویس دهنده رویداد sync را دریافت می کند مجدداً امتحان می شود (این اتفاق زمانی می افتد که مرورگر فکر می کند اتصال بازیابی شده است). مرورگرهایی که از BackgroundSync API پشتیبانی نمیکنند، هر بار که سرویسکار راهاندازی میشود، صف را دوباره امتحان میکنند. برای این کار باید صفحه کنترل کننده سرویس کار اجرا شود، بنابراین چندان موثر نخواهد بود.
آزمایش همگامسازی پسزمینه Workbox
متأسفانه، آزمایش BackgroundSync به دلایلی تا حدودی غیرمعمول و دشوار است.
بهترین روش برای آزمایش پیاده سازی، انجام موارد زیر است:
- یک صفحه را بارگیری کنید و کارگر خدمات خود را ثبت کنید.
- شبکه کامپیوتر خود را خاموش کنید یا وب سرور خود را خاموش کنید.
- از CHROME DEVTOOLS آفلاین استفاده نکنید. چک باکس آفلاین در DevTools فقط بر درخواستهای صفحه تأثیر میگذارد. درخواستهای کارکنان خدمات ادامه خواهد یافت.
- درخواست های شبکه ای را ایجاد کنید که باید با Workbox Background Sync در صف قرار گیرند.
- میتوانید با جستجو در
Chrome DevTools > Application > IndexedDB > workbox-background-sync > requestsبررسی کنید که درخواستها در صف قرار گرفتهاند.
- میتوانید با جستجو در
- حالا شبکه یا وب سرور خود را روشن کنید.
با رفتن به
Chrome DevTools > Application > Service Workers، یک رویدادsyncاولیه را اجباری کنید، نام برچسبworkbox-background-sync:<your queue name>که در آن<your queue name>باید نام صفی باشد که تنظیم کردهاید، و سپس با کلیک بر روی دکمه "همگام سازی".
باید مشاهده کنید که درخواستهای شبکه برای درخواستهای ناموفق انجام میشوند و دادههای IndexedDB اکنون باید خالی باشند زیرا درخواستها با موفقیت دوباره پخش شدهاند.
انواع
BackgroundSyncPlugin
کلاسی که بازگشت به تماس چرخه حیات fetchDidFail را اجرا می کند. این کار اضافه کردن درخواست های ناموفق را به صف همگام سازی پس زمینه آسان تر می کند.
خواص
- سازنده
باطل
تابع
constructorبه صورت زیر است:(name: string, options?: QueueOptions) => {...}
- نام
رشته
برای جزئیات پارامتر به مستندات
workbox-background-sync.Queueمراجعه کنید. - گزینه ها
QueueOptions اختیاری است
- برمی گرداند
Queue
کلاسی برای مدیریت ذخیره درخواست های ناموفق در IndexedDB و امتحان مجدد آنها بعدا. تمام بخشهای فرآیند ذخیرهسازی و پخش مجدد از طریق callback قابل مشاهده است.
خواص
- سازنده
باطل
با گزینه های داده شده یک نمونه از Queue ایجاد می کند
تابع
constructorبه صورت زیر است:(name: string, options?: QueueOptions) => {...}
- نام
رشته
نام منحصر به فرد این صف. این نام باید منحصر به فرد باشد زیرا برای ثبت رویدادهای همگام سازی و ذخیره درخواست ها در IndexedDB مخصوص این نمونه استفاده می شود. اگر یک نام تکراری شناسایی شود، خطایی ایجاد می شود.
- گزینه ها
QueueOptions اختیاری است
- برمی گرداند
- نام
رشته
- دریافت همه
باطل
همه ورودیهایی را که منقضی نشدهاند (به ازای
maxRetentionTime) برمیگرداند. هر ورودی منقضی شده از صف حذف می شود.تابع
getAllبه شکل زیر است:() => {...}- برمی گرداند
Promise<QueueEntry[]>
- popRequest
باطل
آخرین درخواست موجود در صف را حذف می کند و برمی گرداند (همراه با مهر زمانی آن و هر متادیتا). شیء برگشتی به شکل:
{request, timestamp, metadata}.تابع
popRequestبه نظر می رسد:() => {...}- برمی گرداند
Promise<QueueEntry>
- pushRequest
باطل
درخواست ارسال شده را در IndexedDB (همراه با مهر زمانی و هر ابرداده) در انتهای صف ذخیره می کند.
تابع
pushRequestبه نظر می رسد:(entry: QueueEntry) => {...}
- ورود
QueueEntry
- برمی گرداند
قول<باطل>
- registerSync
باطل
یک رویداد همگام سازی را با یک برچسب منحصر به فرد برای این نمونه ثبت می کند.
تابع
registerSyncبه نظر می رسد:() => {...}- برمی گرداند
قول<باطل>
- درخواست های مجدد
باطل
از طریق هر درخواست در صف حلقه می زند و سعی می کند دوباره آن را واکشی کند. اگر هر درخواستی دوباره واکشی نشود، در همان موقعیت در صف قرار میگیرد (که تلاش مجدد را برای رویداد همگامسازی بعدی ثبت میکند).
تابع
replayRequestsبه نظر می رسد:() => {...}- برمی گرداند
قول<باطل>
- shiftRequest
باطل
اولین درخواست موجود در صف را حذف می کند و برمی گرداند (همراه با مهر زمانی آن و هر متادیتا). شیء برگشتی به شکل:
{request, timestamp, metadata}.تابع
shiftRequestبه نظر می رسد:() => {...}- برمی گرداند
Promise<QueueEntry>
- اندازه
باطل
تعداد ورودیهای موجود در صف را برمیگرداند. توجه داشته باشید که ورودی های منقضی شده (در هر
maxRetentionTime) نیز در این تعداد گنجانده شده است.تابع
sizeبه نظر می رسد:() => {...}- برمی گرداند
قول <تعداد>
- unshiftRequest
باطل
درخواست ارسال شده را در IndexedDB (با مهر زمانی و هر ابرداده ای) در ابتدای صف ذخیره می کند.
تابع
unshiftRequestبه نظر می رسد:(entry: QueueEntry) => {...}
- ورود
QueueEntry
- برمی گرداند
قول<باطل>
QueueOptions
خواص
- forceSyncFallback
بولی اختیاری
- maxRetentionTime
شماره اختیاری
- onSync
OnSyncCallback اختیاری است
QueueStore
کلاسی برای مدیریت درخواستهای ذخیرهسازی از یک صف در IndexedDB، که برای دسترسی آسانتر با نام صف فهرستبندی میشود.
اکثر توسعه دهندگان نیازی به دسترسی مستقیم به این کلاس ندارند. آن را برای موارد استفاده پیشرفته در معرض.
خواص
- سازنده
باطل
این نمونه را با یک نمونه Queue مرتبط می کند، بنابراین ورودی های اضافه شده را می توان با نام صف آنها شناسایی کرد.
تابع
constructorبه صورت زیر است:(queueName: string) => {...}
- queueName
رشته
- برمی گرداند
- حذف ورودی
باطل
ورودی شناسه داده شده را حذف می کند.
اخطار: این روش تضمین نمی کند که ورودی حذف شده متعلق به این صف باشد (یعنی مطابق با
queueNameباشد). اما این محدودیت قابل قبول است زیرا این کلاس در معرض عموم قرار نمی گیرد. بررسی اضافی این روش را کندتر از آنچه لازم است می کند.تابع
deleteEntryبه شکل زیر است:(id: number) => {...}
- شناسه
شماره
- برمی گرداند
قول<باطل>
- دریافت همه
باطل
همه ورودیهای فروشگاه مطابق با
queueNameرا برمیگرداند.تابع
getAllبه شکل زیر است:() => {...}- برمی گرداند
Promise<QueueStoreEntry[]>
- popEntry
باطل
آخرین ورودی صف مطابق با
queueNameرا حذف می کند و برمی گرداند.تابع
popEntryبه شکل زیر است:() => {...}- برمی گرداند
Promise<QueueStoreEntry>
- pushEntry
باطل
آخرین ورودی را در صف اضافه کنید.
تابع
pushEntryبه شکل زیر است:(entry: UnidentifiedQueueStoreEntry) => {...}
- ورود
UnidentifiedQueueStoreEntry
- برمی گرداند
قول<باطل>
- shiftEntry
باطل
اولین ورودی صف مطابق با
queueNameرا حذف می کند و برمی گرداند.تابع
shiftEntryبه شکل زیر است:() => {...}- برمی گرداند
Promise<QueueStoreEntry>
- اندازه
باطل
تعداد ورودیهای موجود در فروشگاه را برمیگرداند که با
queueNameمطابقت دارند.تابع
sizeبه نظر می رسد:() => {...}- برمی گرداند
قول <تعداد>
- unshiftEntry
باطل
ابتدا یک ورودی را در صف قرار دهید.
تابع
unshiftEntryبه شکل زیر است:(entry: UnidentifiedQueueStoreEntry) => {...}
- ورود
UnidentifiedQueueStoreEntry
- برمی گرداند
قول<باطل>
StorableRequest
کلاسی برای آسانتر کردن سریالسازی و سریالزدایی درخواستها تا بتوان آنها را در IndexedDB ذخیره کرد.
اکثر توسعه دهندگان نیازی به دسترسی مستقیم به این کلاس ندارند. آن را برای موارد استفاده پیشرفته در معرض.
خواص
- سازنده
باطل
یک شی از دادههای درخواست را میپذیرد که میتوان از آن برای ساخت یک
Requestاستفاده کرد، اما میتواند در IndexedDB نیز ذخیره شود.تابع
constructorبه صورت زیر است:(requestData: RequestData) => {...}
- درخواست داده
RequestData
یک شی از دادههای درخواست که شامل
urlبهعلاوه هر ویژگی مرتبط [requestInit]https://fetch.spec.whatwg.org/#requestinitاست.
- برمی گرداند
- کلون
باطل
یک کلون عمیق از نمونه را ایجاد و برمی گرداند.
تابع
cloneبه نظر می رسد:() => {...}- برمی گرداند
- toObject
باطل
یک کلون عمیق از شیء نمونه
_requestDataرا برمی گرداند.تابع
toObjectبه شکل زیر است:() => {...}- برمی گرداند
RequestData
- به درخواست
باطل
این نمونه را به یک درخواست تبدیل می کند.
تابع
toRequestبه نظر می رسد:() => {...}- برمی گرداند
درخواست کنید
- از درخواست
باطل
یک شی Request را به یک شیء ساده تبدیل می کند که می تواند ساختاری شبیه سازی شده یا رشته ای JSON داشته باشد.
تابع
fromRequestبه شکل زیر است:(request: Request) => {...}
- درخواست کنید
درخواست کنید
- برمی گرداند
Promise< StorableRequest >