כששולחים נתונים לשרת אינטרנט, לפעמים הבקשות נכשלות. הוא ייתכן שהמשתמש איבד את הקישוריות, או השרת מושבת; בכל מקרה, כדאי בדרך כלל לנסות לשלוח את הבקשות מאוחר יותר.
ה-BackgroundSync API החדש
הוא פתרון אידיאלי לבעיה הזו. כש-Service Worker מזהה
בקשת הרשת נכשלה, היא יכולה להירשם לקבלת אירוע sync
,
שנשלח כשהדפדפן מזהה קישוריות שחזרה.
חשוב לזכור שניתן להעביר את אירוע הסנכרון גם אם המשתמש יצא
, ולכן היא הרבה יותר יעילה מהשיטה המסורתית
מתבצע ניסיון חוזר של בקשות שנכשלו.
'סנכרון ברקע של תיבת העבודה' נועד להקל על השימוש BackgroundSync API ושילוב השימוש שלו עם מודולים אחרים של Workbox. הוא מיישם גם אסטרטגיה חלופית לדפדפנים שעדיין לא מטמיעים BackgroundSync.
דפדפנים שתומכים ב-BackgroundSync API מפעילים מחדש באופן אוטומטי את כישלון בקשות בשמך מרווח הזמן שמנוהל על ידי הדפדפן, סביר להניח שנעשה שימוש בהשהיה מעריכית לפני ניסיון חוזר (exponential backoff) בין ניסיונות הפעלה חוזרת. בדפדפנים אינם תומכים במקור ב-BackgroundSync API, 'סנכרון ברקע של Workbox' ינסה להפעיל מחדש באופן אוטומטי בכל פעם שה-Service Worker מופעל.
שימוש בסיסי
הדרך הקלה ביותר להשתמש ב'סנכרון ברקע' היא להשתמש ב-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
קטעי הוק (hooks) אל
קריאה חוזרת (callback) של הפלאגין 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' מספקת גם מחלקה Queue
, שאותה אפשר
יצירת מופע והוספה של בקשות שנכשלו. הבקשות שנכשלו נשמרות
ב-IndexedDB
ומנסים שוב כשהדפדפן חושב שהקישוריות משוחזרת (כלומר,
כשהוא מקבל את אירוע הסנכרון).
יצירת תור
כדי ליצור תור לסנכרון ברקע של Workbox, צריך ליצור אותו עם שם תור (שחייב להיות ייחודי origin):
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
שם התור משמש כחלק משם התג שמתקבל
register()
ברחבי העולם
SyncManager
זו
משמש גם
שם מאגר האובייקטים של
מסד הנתונים IndexedDB.
הוספת בקשה לתור
אחרי שיוצרים מופע מסוג 'הבאים בתור', אפשר להוסיף לו בקשות שנכשלו.
כדי להוסיף בקשה שנכשלה, יש להפעיל את השיטה .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());
});
לאחר הוספת הבקשה לתור, הבקשה תנסה שוב באופן אוטומטי כאשר
ה-service worker מקבל את האירוע sync
(שמתרחש כשהדפדפן
שחושב שהקישוריות שוחזרה). דפדפנים שלא תומכים ב-
BackgroundSync API ינסה לגשת שוב לתור בכל פעם ש-Service Worker
בתהליך. לשם כך נדרש הדף השולט ב-Service Worker
אז היא לא תהיה יעילה באותה מידה.
בדיקת סנכרון ברקע של תיבת העבודה
לצערי, הבדיקה של BackgroundSync די לא אינטואיטיבית וקשה מכמה סיבות.
הגישה הטובה ביותר לבדיקת ההטמעה היא לבצע את הפעולות הבאות:
- טוענים דף ורושמים את Service Worker.
- משביתים את הרשת של המחשב או את שרת האינטרנט.
- אין להשתמש בכלי הפיתוח ל-Chrome ללא חיבור לאינטרנט. תיבת הסימון למצב אופליין ב- כלי הפיתוח משפיעים רק על בקשות מהדף. בקשות של קובץ שירות (service worker) ימשיכו לפעול.
- יצירת בקשות רשת שצריך להוסיף לתור עם 'סנכרון ברקע של Workbox'.
- אפשר לבדוק שהבקשות הגיעו לתור
Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
- אפשר לבדוק שהבקשות הגיעו לתור
- עכשיו מפעילים את הרשת או את שרת האינטרנט.
אילוץ אירוע
sync
מוקדם באמצעות מעבר אלChrome DevTools > Application > Service Workers
, הזנת שם התג שלworkbox-background-sync:<your queue name>
במקום<your queue name>
צריך להיות שם התור שהגדרת, ולאחר מכן לחיצה על 'סנכרון' לחצן.אתם אמורים לראות שמתבצעות בקשות רשת עבור הבקשות שנכשלו וגם נתוני IndexedDB אמורים להיות ריקים עכשיו כי הבקשות הופעל מחדש בהצלחה.
סוגים
BackgroundSyncPlugin
מחלקה שמממשת את הקריאה החוזרת (callback) של מחזור החיים fetchDidFail
. ככה
קל יותר להוסיף בקשות שנכשלו לתור לסנכרון ברקע.
מאפיינים
-
constructor
ריק
הפונקציה
constructor
נראית כך:(name: string, options?: QueueOptions) => {...}
-
שם
מחרוזת
פרטים נוספים זמינים ב
workbox-background-sync.Queue
לקבלת פרטים על הפרמטרים. -
אפשרויות
QueueOptions אופציונלי
-
החזרות
-
Queue
מחלקה לניהול אחסון בקשות שנכשלו ב-IndexedDB וניסיון חוזר שלהן מאוחר יותר. ניתן לצפות בכל החלקים של תהליך האחסון וההפעלה מחדש דרך קריאה חוזרת (callback).
מאפיינים
-
constructor
ריק
יצירת מופע של Queue עם האפשרויות הנתונות
הפונקציה
constructor
נראית כך:(name: string, options?: QueueOptions) => {...}
-
שם
מחרוזת
השם הייחודי של התור הזה. השם חייב להיות ייחודיות כי הוא משמש לרישום אירועי סנכרון ובקשות לחנות ב-IndexedDB שהוא ספציפי למכונה הזו. תישלח שגיאה אם זוהה שם כפול.
-
אפשרויות
QueueOptions אופציונלי
-
החזרות
-
-
שם
מחרוזת
-
getAll
ריק
הפונקציה מחזירה את כל הרשומות שהתוקף שלהן לא פג (לכל
maxRetentionTime
). כל הערכים שהתוקף שלהם פג יוסרו מ'הבאים בתור'.הפונקציה
getAll
נראית כך:() => {...}
-
החזרות
Promise<QueueEntry[]>
-
-
popRequest
ריק
הסרה והחזרה של הבקשה האחרונה בתור (יחד עם חותמת זמן וכל מטא-נתונים). האובייקט המוחזר מופיע בפורמט:
{request, timestamp, metadata}
הפונקציה
popRequest
נראית כך:() => {...}
-
החזרות
Promise<QueueEntry>
-
-
pushRequest
ריק
שמירת הבקשה שהועברה ב-IndexedDB (עם חותמת הזמן וכל בסוף התור.
הפונקציה
pushRequest
נראית כך:(entry: QueueEntry) => {...}
-
ערך
QueueEntry
-
החזרות
הבטחה<Empty>
-
-
registerSync
ריק
רושם אירוע סנכרון עם תג ייחודי למופע הזה.
הפונקציה
registerSync
נראית כך:() => {...}
-
החזרות
הבטחה<Empty>
-
-
replayRequests
ריק
המערכת עוברת בלולאה על כל בקשה בתור ומנסה לאחזר אותה מחדש. אם בקשה כלשהי לא מצליחה לאחזר מחדש את הנתונים, היא מוחזרת לאותו מיקום התור (שרושם ניסיון חוזר לאירוע הסנכרון הבא).
הפונקציה
replayRequests
נראית כך:() => {...}
-
החזרות
הבטחה<Empty>
-
-
shiftRequest
ריק
הסרה והחזרה של הבקשה הראשונה בתור (יחד עם חותמת זמן וכל מטא-נתונים). האובייקט המוחזר מופיע בפורמט:
{request, timestamp, metadata}
הפונקציה
shiftRequest
נראית כך:() => {...}
-
החזרות
Promise<QueueEntry>
-
-
size
ריק
מחזירה את מספר הערכים שנמצאים בתור. חשוב לשים לב שגם רשומות שהתוקף שלהן פג (לכל
maxRetentionTime
) נכללות בספירה הזו.הפונקציה
size
נראית כך:() => {...}
-
החזרות
Promise<number>
-
-
unshiftRequest
ריק
שמירת הבקשה שהועברה ב-IndexedDB (עם חותמת הזמן וכל מטא-נתונים) בתחילת התור.
הפונקציה
unshiftRequest
נראית כך:(entry: QueueEntry) => {...}
-
ערך
QueueEntry
-
החזרות
הבטחה<Empty>
-
QueueOptions
מאפיינים
-
forceSyncFallback
ערך בוליאני אופציונלי
-
maxRetentionTime
מספר אופציונלי
-
onSync
OnSyncCallback (אופציונלי) אופציונלי
QueueStore
מחלקה לניהול בקשות אחסון מתור ב-IndexedDB, נוספו לאינדקס לפי שם התור כדי לגשת אליהן בקלות.
רוב המפתחים לא יצטרכו לגשת לכיתה הזו ישירות. הוא חשוף בתרחישים מתקדמים לדוגמה.
מאפיינים
-
constructor
ריק
משייך את המופע הזה למופע של 'תור', כך שערכים שנוספו יכולים להיות מזוהה לפי שם התור.
הפונקציה
constructor
נראית כך:(queueName: string) => {...}
-
queueName
מחרוזת
-
החזרות
-
-
deleteEntry
ריק
מוחק את הרשומה של המזהה הנתון.
אזהרה: השיטה הזו לא מבטיחה שהרשומה שנמחקה שייכת תור (כלומר תואם ל-
queueName
). אבל ההגבלה הזו מקובלת. כי הסיווג הזה לא גלוי לכולם. בדיקה נוספת תאפשר השיטה הזו איטית יותר ממה שהיא צריכה.הפונקציה
deleteEntry
נראית כך:(id: number) => {...}
-
id [מזהה]
number
-
החזרות
הבטחה<Empty>
-
-
getAll
ריק
הפונקציה מחזירה את כל הרשומות בחנות שתואמות לערך
queueName
.הפונקציה
getAll
נראית כך:() => {...}
-
החזרות
Promise<QueueStoreEntry[]>
-
-
popEntry
ריק
הפונקציה מסירה ומחזירה את הערך האחרון בתור שתואם ל-
queueName
.הפונקציה
popEntry
נראית כך:() => {...}
-
החזרות
Promise<QueueStoreEntry>
-
-
pushEntry
ריק
צירוף רשומה אחרונה בתור.
הפונקציה
pushEntry
נראית כך:(entry: UnidentifiedQueueStoreEntry) => {...}
-
ערך
UnidentifiedQueueStoreEntry
-
החזרות
הבטחה<Empty>
-
-
shiftEntry
ריק
הפונקציה מסירה ומחזירה את הרשומה הראשונה בתור שתואמת ל-
queueName
.הפונקציה
shiftEntry
נראית כך:() => {...}
-
החזרות
Promise<QueueStoreEntry>
-
-
size
ריק
הפונקציה מחזירה את מספר הרשומות בחנות שתואמות ל-
queueName
.הפונקציה
size
נראית כך:() => {...}
-
החזרות
Promise<number>
-
-
unshiftEntry
ריק
צריך להוסיף רשומה ראשונה בתור.
הפונקציה
unshiftEntry
נראית כך:(entry: UnidentifiedQueueStoreEntry) => {...}
-
ערך
UnidentifiedQueueStoreEntry
-
החזרות
הבטחה<Empty>
-
StorableRequest
כיתה שמקלה על הסידור והסידור של בקשות לפי סריאליזציה, כך שהן אפשר לאחסן ב-IndexedDB.
רוב המפתחים לא יצטרכו לגשת לכיתה הזו ישירות. הוא חשוף בתרחישים מתקדמים לדוגמה.
מאפיינים
-
constructor
ריק
מקבל אובייקט של נתוני בקשה שיכול לשמש לבניית אובייקט
Request
אבל ניתן לאחסן אותו גם ב-IndexedDB.הפונקציה
constructor
נראית כך:(requestData: RequestData) => {...}
-
requestData
RequestData
אובייקט של נתוני בקשה שכולל את המאפיין
url
בתוספת כל מאפיין רלוונטי של [requestInit]https://fetch.spec.whatwg.org/#requestinit
.
-
החזרות
-
-
שכפל
ריק
יצירה והחזרה של שכפול עמוק של המכונה.
הפונקציה
clone
נראית כך:() => {...}
-
החזרות
-
-
toObject
ריק
מחזירה שכפול עמוק של המופעים
_requestData
.הפונקציה
toObject
נראית כך:() => {...}
-
החזרות
RequestData
-
-
toRequest
ריק
הפונקציה ממירה את המופע הזה ל-Request.
הפונקציה
toRequest
נראית כך:() => {...}
-
החזרות
בקשה
-
-
fromRequest
ריק
ממירה אובייקט Request [בקשה] לאובייקט פשוט שיכול להיות מובנה שכפול או מחרוזת JSON.
הפונקציה
fromRequest
נראית כך:(request: Request) => {...}
-
בקשה
בקשה
-
החזרות
Promise<StorableRequest>
-