वेब सर्वर पर डेटा भेजते समय, कभी-कभी अनुरोध पूरे नहीं हो पाते. इसकी वजह यह हो सकती है कि उपयोगकर्ता ने इंटरनेट से कनेक्ट न कर रखा हो या सर्वर के काम न करने की वजह से भी ऐसा हो सकता है. दोनों ही मामलों में, आपको बार-बार बाद में अनुरोध भेजने की कोशिश करनी चाहिए.
इस समस्या को हल करने के लिए, नया backgroundSync API इस्तेमाल करें. जब किसी सर्विस वर्कर को पता चलता है कि नेटवर्क अनुरोध पूरा नहीं हो सका, तो वह sync
इवेंट पाने के लिए रजिस्टर कर सकता है. यह इवेंट तब डिलीवर होता है, जब ब्राउज़र को लगता है कि कनेक्टिविटी वापस आ गई है.
ध्यान दें कि सिंक इवेंट को डिलीवर किया जा सकता है, भले ही उपयोगकर्ता ने ऐप्लिकेशन छोड़ दिया हो. यह, पूरे न हो पाने वाले अनुरोधों के लिए फिर से कोशिश करने के पारंपरिक तरीके से ज़्यादा असरदार होता है.
वर्कबॉक्स बैकग्राउंड सिंक को इस तरह से डिज़ाइन किया गया है कि आप जिसके लिए बैकग्राउंड सिंक एपीआई आसानी से इस्तेमाल करना है और उसके इस्तेमाल को अन्य वर्कबॉक्स मॉड्यूल के साथ जोड़ना है. यह ऐसे ब्राउज़र के लिए फ़ॉलबैक की रणनीति भी लागू करता है जिन पर बैकग्राउंड सिंक लागू नहीं होते हैं.
बैकग्राउंड सिंक एपीआई के साथ काम करने वाले ब्राउज़र, ब्राउज़र से मैनेज किए जाने वाले इंटरवल पर आपकी ओर से पूरे न हो पाने वाले अनुरोधों को अपने-आप फिर से चलाने की कोशिश करेंगे. ऐसा रीप्ले की कोशिशों के बीच एक्सपोनेन्शियल बैकऑफ़ का इस्तेमाल करके किया जा सकता है. अगर किसी ब्राउज़र में बैकग्राउंड सिंक एपीआई की सुविधा मूल रूप से काम नहीं करती है, तो Workbox बैकग्राउंड सिंक की सुविधा आपके सर्विस वर्कर के चालू होने पर, उसे अपने-आप फिर से चलाने की कोशिश करेगी.
बुनियादी इस्तेमाल
बैकग्राउंड सिंक की सुविधा को इस्तेमाल करने का सबसे आसान तरीका 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
का स्टेटस शामिल है, जैसे कि 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.
बेहतर इस्तेमाल
वर्कबॉक्स बैकग्राउंड सिंक के लिए एक Queue
क्लास भी मिलती है, जिसे तुरंत शुरू किया जा सकता है. साथ ही, पूरे न हो पाने वाले अनुरोधों को जोड़ा भी जा सकता है. पूरे न हो पाने वाले अनुरोधों को IndexedDB में सेव किया जाता है. ब्राउज़र को लगता है कि कनेक्टिविटी वापस आ गई है (जैसे, जब इसे सिंक इवेंट मिलता है), तब फिर से कोशिश की जाती है.
सूची बनाई जा रही है
वर्कबॉक्स बैकग्राउंड सिंक सूची बनाने के लिए, आपको इसे सूची के नाम से बनाना होगा (जो आपके ऑरिजिन के लिए अलग होना चाहिए):
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
सूची के नाम का इस्तेमाल, टैग के नाम के हिस्से के तौर पर किया जाता है, जिसे ग्लोबल SyncManager
से register()
मिलता है. इसका इस्तेमाल,
IndexedDB डेटाबेस के
Object Store नाम के तौर पर भी किया जाता है.
सूची में एक अनुरोध जोड़ा जा रहा है
सूची बनाने के बाद, उसमें पूरे न हो पाने वाले अनुरोधों को जोड़ा जा सकता है.
.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
इवेंट मिलने पर, अनुरोध अपने-आप फिर से किया जाता है. ऐसा तब होता है, जब ब्राउज़र को कनेक्टिविटी वापस मिल जाती है. जो ब्राउज़र बैकग्राउंडसिंक एपीआई के साथ काम नहीं करते वे हर बार सर्विस वर्कर के चालू होने पर,
सूची को फिर से कोशिश करेंगे. इसके लिए सर्विस वर्कर को कंट्रोल करने वाले पेज को चलाना ज़रूरी होता है, इसलिए यह ज़्यादा असरदार नहीं होगा.
Workbox बैकग्राउंड सिंक की जांच करना
अफ़सोस की बात यह है कि कई वजहों से बैकग्राउंड सिंक को टेस्ट करना कुछ हद तक मुश्किल और मुश्किल होता है.
लागू करने की प्रोसेस की जांच करने का सबसे अच्छा तरीका यह है कि:
- कोई पेज लोड करें और अपने सर्विस वर्कर को रजिस्टर करें.
- अपने कंप्यूटर का नेटवर्क बंद करें या अपना वेब सर्वर बंद करें.
- Chrome DevTools का ऑफ़लाइन इस्तेमाल न करें. DevTool में ऑफ़लाइन चेकबॉक्स सिर्फ़ पेज से मिलने वाले अनुरोधों पर असर डालता है. सर्विस वर्कर के अनुरोध मिलते रहेंगे.
- ऐसे नेटवर्क अनुरोध करें जिन्हें वर्कबॉक्स बैकग्राउंड सिंक की मदद से सूची में शामिल किया जाना चाहिए.
Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
में देखकर यह पता लगाया जा सकता है कि अनुरोध सूची में जोड़े गए हैं या नहीं
- अब अपना नेटवर्क या वेब सर्वर चालू करें.
Chrome DevTools > Application > Service Workers
पर जाकर,workbox-background-sync:<your queue name>
में टैग का नाम डालें, जहां<your queue name>
आपकी सेट की गई सूची का नाम होना चाहिए. इसके बाद, 'सिंक करें' बटन पर क्लिक करके,sync
वाले शुरुआती इवेंट को हर हाल में लागू करें.आपको पूरे न हो पाने वाले अनुरोधों के लिए नेटवर्क अनुरोध करते हुए देखना चाहिए और IndexedDB डेटा अब खाली रहना चाहिए, क्योंकि अनुरोध पूरे हो चुके हैं.
टाइप
BackgroundSyncPlugin
fetchDidFail
लाइफ़साइकल कॉलबैक को लागू करने वाली क्लास. इससे बैकग्राउंड सिंक की सूची में, पूरे न हो पाने वाले अनुरोधों को जोड़ना आसान हो जाता है.
प्रॉपर्टी
-
कंस्ट्रक्टर
void
constructor
फ़ंक्शन ऐसा दिखता है:(name: string, options?: QueueOptions) => {...}
-
नाम
स्ट्रिंग
पैरामीटर की जानकारी के लिए,
workbox-background-sync.Queue
दस्तावेज़ देखें. -
विकल्प
QueueOptions ज़रूरी नहीं है
-
returns
-
Queue
IndexedDB में, पूरे न हो पाने वाले अनुरोधों को मैनेज करने और उन्हें बाद में प्रोसेस करने की कोशिश करने वाली क्लास. डेटा को सेव करने और फिर से चलाने की प्रोसेस के सभी हिस्सों का पता लगाने के लिए कॉलबैक की मदद ली जाती है.
प्रॉपर्टी
-
कंस्ट्रक्टर
void
दिए गए विकल्पों के साथ सूची का एक इंस्टेंस बनाता है
constructor
फ़ंक्शन ऐसा दिखता है:(name: string, options?: QueueOptions) => {...}
-
नाम
स्ट्रिंग
इस सूची का यूनीक नाम. यह नाम यूनीक होना चाहिए, क्योंकि इसका इस्तेमाल इस इंस्टेंस के लिए खास तौर पर दिए गए IndexedDB में, सिंक इवेंट को रजिस्टर करने और अनुरोधों को स्टोर करने के लिए किया जाता है. डुप्लीकेट नाम मिलने पर गड़बड़ी होगी.
-
विकल्प
QueueOptions ज़रूरी नहीं है
-
returns
-
-
नाम
स्ट्रिंग
-
getAll
void
वे सभी एंट्री देता है जिनकी समयसीमा खत्म नहीं हुई है (हर
maxRetentionTime
के हिसाब से). वे एंट्री सूची से हटा दी जाती हैं जिनकी समयसीमा खत्म हो चुकी है.getAll
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<QueueEntry[]>
-
-
popRequest
void
सूची में मौजूद आखिरी अनुरोध (टाइमस्टैंप और सभी मेटाडेटा के साथ) को हटा देता है और दिखाता है. दिखाया गया ऑब्जेक्ट इस रूप में होता है:
{request, timestamp, metadata}
.popRequest
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<QueueEntry>
-
-
pushRequest
void
पास किए गए अनुरोध को सूची के आखिर में IndexedDB (इसके टाइमस्टैंप और किसी भी मेटाडेटा के साथ) में सेव करता है.
pushRequest
फ़ंक्शन ऐसा दिखता है:(entry: QueueEntry) => {...}
-
एंट्री
QueueEntry
-
returns
Promise<void>
-
-
registerSync
void
इस इंस्टेंस के लिए खास टैग वाले सिंक इवेंट को रजिस्टर करता है.
registerSync
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<void>
-
-
replayRequests
void
सूची में मौजूद हर अनुरोध से लूप करता है और उसे फिर से फ़ेच करने की कोशिश करता है. अगर कोई अनुरोध फिर से फ़ेच नहीं हो पाता है, तो उसे सूची में वापस उसी जगह पर रखा जाता है. इससे अगले सिंक इवेंट के लिए, फिर से कोशिश करने को रजिस्टर किया जाता है.
replayRequests
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<void>
-
-
shiftRequest
void
सूची में मौजूद पहले अनुरोध को हटाता है और वापस करता है. इसमें टाइमस्टैंप और सभी मेटाडेटा भी शामिल होते हैं. दिखाया गया ऑब्जेक्ट इस रूप में होता है:
{request, timestamp, metadata}
.shiftRequest
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<QueueEntry>
-
-
साइज़
void
यह फ़ंक्शन सूची में मौजूद एंट्री की संख्या दिखाता है. ध्यान दें कि इस संख्या में ऐसी एंट्री भी शामिल हैं जिनकी समयसीमा खत्म हो चुकी है (हर
maxRetentionTime
के हिसाब से).size
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
वादा<number>
-
-
unshiftRequest
void
पास किए गए अनुरोध को सूची की शुरुआत में IndexedDB (इसके टाइमस्टैंप और किसी भी मेटाडेटा के साथ) में स्टोर करता है.
unshiftRequest
फ़ंक्शन ऐसा दिखता है:(entry: QueueEntry) => {...}
-
एंट्री
QueueEntry
-
returns
Promise<void>
-
QueueOptions
प्रॉपर्टी
-
forceSyncFallback
बूलियन ज़रूरी नहीं
-
maxRetentionTime
नंबर ज़रूरी नहीं
-
onSync
OnSyncCallback ज़रूरी नहीं
QueueStore
यह क्लास IndexedDB की किसी सूची से स्टोर करने के अनुरोधों को मैनेज करने वाली क्लास. इसे आसानी से ऐक्सेस करने के लिए, सूची के नाम से इंडेक्स किया जाता है.
ज़्यादातर डेवलपर को सीधे इस क्लास को ऐक्सेस करने की ज़रूरत नहीं होगी. इसे बेहतर इस्तेमाल के लिए उपलब्ध कराया जाता है.
प्रॉपर्टी
-
कंस्ट्रक्टर
void
इस इंस्टेंस को सूची के इंस्टेंस से जोड़ता है, ताकि जोड़ी गई एंट्री को उनकी सूची के नाम से पहचाना जा सके.
constructor
फ़ंक्शन ऐसा दिखता है:(queueName: string) => {...}
-
queueName
स्ट्रिंग
-
returns
-
-
deleteEntry
void
दी गई आईडी की एंट्री मिटा देता है.
चेतावनी: यह तरीका यह पक्का नहीं करता है कि मिटाई गई एंट्री इस सूची से जुड़ी है (यानी कि
queueName
से मेल खाती है). हालांकि, यह सीमा स्वीकार की जा सकती है, क्योंकि इस क्लास को सार्वजनिक तौर पर नहीं दिखाया जाता है. अगर फिर से जांच की जाए, तो यह तरीका ज़रूरत से ज़्यादा धीमा हो जाएगा.deleteEntry
फ़ंक्शन ऐसा दिखता है:(id: number) => {...}
-
id
नंबर
-
returns
Promise<void>
-
-
getAll
void
स्टोर में
queueName
से मेल खाने वाली सभी एंट्री दिखाता है.getAll
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<QueueStoreEntry[]>
-
-
popEntry
void
queueName
से मेल खाने वाली सूची की आखिरी एंट्री को हटाता है और लौटाता है.popEntry
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
pushEntry
void
सूची के आखिर में एंट्री जोड़ें.
pushEntry
फ़ंक्शन ऐसा दिखता है:(entry: UnidentifiedQueueStoreEntry) => {...}
-
एंट्री
UnidentifiedQueueStoreEntry
-
returns
Promise<void>
-
-
shiftEntry
void
यह फ़ंक्शन
queueName
से मेल खाने वाली सूची की पहली एंट्री हटाता और दिखाता है.shiftEntry
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
साइज़
void
यह फ़ंक्शन
queueName
से मेल खाने वाले स्टोर में एंट्री की संख्या दिखाता है.size
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
वादा<number>
-
-
unshiftEntry
void
सूची में सबसे पहले एंट्री जोड़ें.
unshiftEntry
फ़ंक्शन ऐसा दिखता है:(entry: UnidentifiedQueueStoreEntry) => {...}
-
एंट्री
UnidentifiedQueueStoreEntry
-
returns
Promise<void>
-
StorableRequest
यह क्लास, अनुरोधों को क्रम से लगाने और बिना क्रम से लगाए जाने वाले अनुरोधों को आसान बनाती है, ताकि उन्हें IndexedDB में स्टोर किया जा सके.
ज़्यादातर डेवलपर को सीधे इस क्लास को ऐक्सेस करने की ज़रूरत नहीं होगी. इसे बेहतर इस्तेमाल के लिए उपलब्ध कराया जाता है.
प्रॉपर्टी
-
कंस्ट्रक्टर
void
यह नीति, अनुरोध किए गए डेटा के ऑब्जेक्ट को स्वीकार करती है. इसका इस्तेमाल
Request
बनाने के लिए किया जा सकता है. हालांकि, इसे IndexedDB में भी सेव किया जा सकता है.constructor
फ़ंक्शन ऐसा दिखता है:(requestData: RequestData) => {...}
-
requestData
RequestData
अनुरोध के डेटा का ऑब्जेक्ट, जिसमें
url
के साथ-साथ [requestInit]https://fetch.spec.whatwg.org/#requestinit
की सभी ज़रूरी प्रॉपर्टी शामिल होती हैं.
-
returns
-
-
क्लोन
void
यह इंस्टेंस का डीप क्लोन बनाता है और दिखाता है.
clone
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
-
-
toObject
void
_requestData
ऑब्जेक्ट के इंस्टेंस का डीप क्लोन दिखाता है.toObject
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
RequestData
-
-
toRequest
void
इस इंस्टेंस को अनुरोध में बदल देता है.
toRequest
फ़ंक्शन ऐसा दिखता है:() => {...}
-
returns
अनुरोध
-
-
fromRequest
void
अनुरोध ऑब्जेक्ट को ऐसे सादे ऑब्जेक्ट में बदलता है जिसे क्लोन किया जा सकता है या JSON स्ट्रिंग में बदला जा सकता है.
fromRequest
फ़ंक्शन ऐसा दिखता है:(request: Request) => {...}
-
CANNOT TRANSLATE
अनुरोध
-
returns
Promise<StorableRequest>
-