هنگامی که داده ها را به یک وب سرور ارسال می کنید، گاهی اوقات درخواست ها با شکست مواجه می شوند. ممکن است به این دلیل باشد که کاربر اتصال خود را از دست داده است، یا ممکن است به دلیل از کار افتادن سرور باشد. در هر صورت اغلب می خواهید درخواست ها را بعداً دوباره ارسال کنید.
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 >