কিছু ক্ষেত্রে, কোনও ওয়েব অ্যাপকে পৃষ্ঠা ও সার্ভিস ওয়ার্কারের মধ্যে দ্বিমুখী কমিউনিকেশন চ্যানেল তৈরি করতে হতে পারে।
যেমন: পডকাস্ট PWA-তে এমন ফিচার তৈরি করা যেতে পারে যার মাধ্যমে ব্যবহারকারী অফলাইনে শোনার জন্য পর্ব ডাউনলোড করতে পারবেন এবং সার্ভিস ওয়ার্কারকে নিয়মিতভাবে প্রোগ্রেস সম্পর্কে পৃষ্ঠাটিকে আপডেট করার অনুমতি দিতে পারবেন, যাতে প্রধান থ্রেড UI আপডেট করতে পারে।
এই গাইডে আমরা Window এবং সার্ভিস ওয়ার্কার কনটেক্সটের মধ্যে দ্বিমুখী কমিউনিকেশন বাস্তবায়িত করার বিভিন্ন উপায় এক্সপ্লোর করব। এর জন্য আমরা বিভিন্ন API, Workbox লাইব্রেরি এবং কিছু উন্নত কেস এক্সপ্লোর করব।
Workbox ব্যবহার করা
workbox-window হল Workbox লাইব্রেরির
মডিউলের একটি সেট যা উইন্ডো প্রসঙ্গে
রান করার জন্য তৈরি করা হয়েছে। Workbox
ক্লাসটি ইনস্ট্যান্সের রেজিস্টার করা সার্ভিস ওয়ার্কারকে মেসেজ পাঠাতে এবং উত্তরের জন্য অপেক্ষা করতে messageSW() পদ্ধতি প্রদান করে।
নিম্নলিখিত পৃষ্ঠা কোড একটি নতুন Workbox ইনস্ট্যান্স তৈরি করে এবং সার্ভিস ওয়ার্কারকে একটি মেসেজ পাঠায়
যাতে এর ভার্সন পাওয়া যায়:
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
সার্ভিস ওয়ার্কার অন্য প্রান্তে মেসেজ লিসেনার প্রয়োগ করে এবং রেজিস্টার করা সার্ভিস ওয়ার্কারকে উত্তর দেয়:
const SW_VERSION = '1.0.0';
self.addEventListener('message', (event) => {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
});
লাইব্রেরিটি একটি ব্রাউজার API ব্যবহার করে যা আমরা পরবর্তী বিভাগে পর্যালোচনা করব: মেসেজ চ্যানেল, তবে অনেক বাস্তবায়নের বিবরণ অ্যাবস্ট্র্যাক্ট করে, এটি ব্যবহার করা সহজ করে তোলে, পাশাপাশি এই API-এর বিস্তৃত ব্রাউজার সহায়তা-এর সুবিধা গ্রহণ করে।
ব্রাউজার API ব্যবহার করে
Workbox লাইব্রেরি আপনার প্রয়োজন মেটানোর জন্য যথেষ্ট না হলে, পৃষ্ঠা ও সার্ভিস ওয়ার্কারের মধ্যে "দ্বিমুখী" কমিউনিকেশন প্রয়োগ করার জন্য একাধিক লোয়ার-লেভেল API উপলভ্য আছে। তাদের মধ্যে কিছু মিল ও অমিল আছে:
মিল:
- সব ক্ষেত্রেই,
postMessage()ইন্টারফেসের মাধ্যমে এক প্রান্ত থেকে কমিউনিকেশন শুরু হয় এবংmessageহ্যান্ডলার প্রয়োগ করে অন্য প্রান্তে তা রিসিভ করা হয়। - বাস্তবে, উপলভ্য সব API আমাদের একই ধরনের ব্যবহারের ক্ষেত্রে প্রয়োগ করার অনুমতি দেয়, তবে এর মধ্যে কিছু API কিছু পরিস্থিতিতে ডেভেলপমেন্টকে সহজ করতে পারে।
পার্থক্য:
- যোগাযোগের অন্য প্রান্তকে শনাক্ত করার জন্য তাদের কাছে বিভিন্ন উপায় রয়েছে: তাদের মধ্যে কেউ কেউ অন্য প্রসঙ্গের একটি স্পষ্ট রেফারেন্স ব্যবহার করে, অন্যরা প্রতিটি প্রান্তে ইনস্ট্যান্টিয়েট করা একটি প্রক্সি অবজেক্টের মাধ্যমে পরোক্ষভাবে যোগাযোগ করতে পারে।
- ব্রাউজার সাপোর্ট এগুলির মধ্যে আলাদা আলাদা হয়।
Broadcast Channel API
Broadcast Channel API BroadcastChannel অবজেক্টের মাধ্যমে ব্রাউজিং কনটেক্সটের মধ্যে প্রাথমিক কমিউনিকেশনের অনুমতি দেয়।
এটি প্রয়োগ করতে, প্রথমে, প্রতিটি কনটেক্সটকে একই আইডি সহ একটি BroadcastChannel অবজেক্ট ইনস্ট্যান্টিয়েট করতে হবে
এবং এটি থেকে মেসেজ পাঠাতে ও গ্রহণ করতে হবে:
const broadcast = new BroadcastChannel('channel-123');
BroadcastChannel অবজেক্ট, যেকোনও লিসেনিং কনটেক্সটে মেসেজ পাঠানোর জন্য postMessage() ইন্টারফেস
এক্সপোজ করে:
//send message
broadcast.postMessage({ type: 'MSG_ID', });
যেকোনও ব্রাউজার কন্টেক্সট BroadcastChannel অবজেক্টের onmessage পদ্ধতির মাধ্যমে মেসেজ শুনতে
পারে:
//listen to messages
broadcast.onmessage = (event) => {
if (event.data && event.data.type === 'MSG_ID') {
//process message...
}
};
যেমন দেখা যাচ্ছে, কোনও নির্দিষ্ট প্রসঙ্গের কোনও স্পষ্ট রেফারেন্স নেই, তাই প্রথমে সার্ভিস ওয়ার্কার বা কোনও নির্দিষ্ট ক্লায়েন্টের রেফারেন্স পাওয়ার প্রয়োজন নেই।
অসুবিধা হল, এই লেখার সময়, API-তে Chrome, Firefox এবং Edge কাজ করে, কিন্তু Safari-এর মতো অন্যান্য ব্রাউজার এখনও কাজ করে না।
ক্লায়েন্ট API
Client API আপনাকে সার্ভিস ওয়ার্কারের নিয়ন্ত্রণ করা অ্যাক্টিভ ট্যাবকে উপস্থাপনকারী সব WindowClient অবজেক্টের রেফারেন্স পেতে সাহায্য করে।
যেহেতু পৃষ্ঠাটি একটিমাত্র সার্ভিস ওয়ার্কার দ্বারা নিয়ন্ত্রিত হয়, তাই এটি serviceWorker ইন্টারফেসের মাধ্যমে সরাসরি অ্যাক্টিভ সার্ভিস ওয়ার্কারকে মেসেজ পাঠায় ও তার মেসেজ শোনে:
//send message
navigator.serviceWorker.controller.postMessage({
type: 'MSG_ID',
});
//listen to messages
navigator.serviceWorker.onmessage = (event) => {
if (event.data && event.data.type === 'MSG_ID') {
//process response
}
};
একইভাবে, সার্ভিস ওয়ার্কার onmessage লিসেনার প্রয়োগ করে মেসেজ শোনে:
//listen to messages
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'MSG_ID') {
//Process message
}
});
কোনও ক্লায়েন্টের সাথে যোগাযোগ করতে, সার্ভিস ওয়ার্কার
Clients.matchAll() এবং
Clients.get()-এর মতো পদ্ধতি প্রয়োগ করে
WindowClient অবজেক্টের অ্যারে পায়। তারপর এটি এগুলির মধ্যে যেকোনও একটি
postMessage() করতে পারে:
//Obtain an array of Window client objects
self.clients.matchAll(options).then(function (clients) {
if (clients && clients.length) {
//Respond to last focused tab
clients[0].postMessage({type: 'MSG_ID'});
}
});
Client API হল তুলনামূলকভাবে সহজ উপায়ে সার্ভিস ওয়ার্কার থেকে সব অ্যাক্টিভ ট্যাবের সাথে সহজে যোগাযোগ করার
একটি ভালো বিকল্প। API সব প্রধান
ব্রাউজারে কাজ করে,
তবে এর সব পদ্ধতি উপলভ্য নাও হতে পারে, তাই আপনার সাইটে এটি প্রয়োগ করার আগে
ব্রাউজার সাপোর্ট চেক করে নিতে ভুলবেন না।
ম্যাসেজ চ্যানেল
মেসেজ চ্যানেল-এর জন্য দ্বিমুখী কমিউনিকেশন চ্যানেল প্রতিষ্ঠা করতে একটি প্রসঙ্গ থেকে অন্য প্রসঙ্গে একটি পোর্ট সংজ্ঞায়িত এবং পাস করতে হবে।
চ্যানেল শুরু করতে, পৃষ্ঠাটি একটি MessageChannel অবজেক্ট ইনস্ট্যান্টিয়েট করে এবং রেজিস্টার করা সার্ভিস ওয়ার্কারকে একটি পোর্ট পাঠাতে এটি ব্যবহার করে। এছাড়াও, পৃষ্ঠাটি অন্য প্রসঙ্গ থেকে মেসেজ পাওয়ার জন্য
এতে একটি onmessage লিসেনার প্রয়োগ করে:
const messageChannel = new MessageChannel();
//Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
messageChannel.port2,
]);
//Listen to messages
messageChannel.port1.onmessage = (event) => {
// Process message
};
সার্ভিস ওয়ার্কার পোর্টটি গ্রহণ করে, এটির একটি রেফারেন্স সেভ করে এবং অন্য দিকে একটি মেসেজ পাঠাতে এটি ব্যবহার করে:
let communicationPort;
//Save reference to port
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PORT_INITIALIZATION') {
communicationPort = event.ports[0];
}
});
//Send messages
communicationPort.postMessage({type: 'MSG_ID'});
MessageChannel বর্তমানে সব প্রধান
ব্রাউজারে কাজ করে।
উন্নত API: ব্যাকগ্রাউন্ড সিঙ্ক এবং ব্যাকগ্রাউন্ড ফেচ
এই গাইডে আমরা তুলনামূলকভাবে সহজ কেসের জন্য দ্বিমুখী কমিউনিকেশন টেকনিক প্রয়োগ করার উপায় এক্সপ্লোর করেছি, যেমন, পারফর্ম করার জন্য অপারেশন বর্ণনা করে এমন স্ট্রিং মেসেজ পাস করা অথবা একটি প্রসঙ্গ থেকে অন্য প্রসঙ্গে ক্যাশে করার জন্য URL-এর তালিকা। এই বিভাগে আমরা নির্দিষ্ট পরিস্থিতি ম্যানেজ করার জন্য দুটি API এক্সপ্লোর করব: কানেক্টিভিটির অভাব এবং দীর্ঘ ডাউনলোড।
ব্যাকগ্রাউন্ড সিঙ্ক
কোনও চ্যাট অ্যাপ হয়ত নিশ্চিত করতে চায় যে খারাপ কানেক্টিভিটির কারণে মেসেজ যেন কখনও হারিয়ে না যায়। ব্যাকগ্রাউন্ড সিঙ্ক API ব্যবহারকারীর স্টেবল কানেক্টিভিটি থাকলে, আপনাকে অ্যাকশন স্থগিত রাখতে দেয়। ব্যবহারকারী যা পাঠাতে চান, তা যাতে পাঠানো হয়, সেটি নিশ্চিত করার জন্য এটি উপযোগী।
postMessage() ইন্টারফেসের পরিবর্তে, পৃষ্ঠাটি একটি sync রেজিস্টার করে:
navigator.serviceWorker.ready.then(function (swRegistration) {
return swRegistration.sync.register('myFirstSync');
});
তারপর মেসেজ প্রসেস করার জন্য সার্ভিস ওয়ার্কার sync ইভেন্ট শোনে:
self.addEventListener('sync', function (event) {
if (event.tag == 'myFirstSync') {
event.waitUntil(doSomeStuff());
}
});
doSomeStuff() ফাংশনটি যা করার চেষ্টা করছে তার সাফল্য/ব্যর্থতা নির্দেশ করে এমন একটি প্রতিশ্রুতি ফেরত দেওয়া উচিত। এটি পূরণ হলে, সিঙ্ক সম্পূর্ণ হয়। এটি ব্যর্থ হলে, আবার চেষ্টা করার জন্য আরেকটি সিঙ্ক শিডিউল করা
হবে। আবার সিঙ্ক করার চেষ্টা করার সময় কানেক্টিভিটির জন্য অপেক্ষা করা হয় এবং এক্সপোনেনশিয়াল ব্যাক-অফ ব্যবহার করা হয়।
অপারেশনটি সম্পন্ন হয়ে গেলে, সার্ভিস ওয়ার্কার UI আপডেট করার জন্য পেজের সাথে আবার যোগাযোগ করতে পারে, এর জন্য আগে এক্সপ্লোর করা যেকোনও কমিউনিকেশন API ব্যবহার করা হয়।
খারাপ কানেক্টিভিটির কারণে ব্যর্থ কোয়েরিগুলি ধরে রাখতে Google Search ব্যাকগ্রাউন্ড সিঙ্ক ব্যবহার করে এবং ব্যবহারকারী অনলাইন হলে পরে সেগুলি আবার চেষ্টা করে। অপারেশনটি সম্পন্ন হলে, তারা ওয়েব থেকে পাঠানো পুশ বিজ্ঞপ্তির মাধ্যমে ব্যবহারকারীকে ফলাফলটি জানান:
ব্যাকগ্রাউন্ড ফেচ
মেসেজ পাঠানো বা ক্যাশে করার জন্য URL-এর তালিকার মতো তুলনামূলকভাবে ছোট কাজের জন্য, এখনও পর্যন্ত এক্সপ্লোর করা বিকল্পগুলি একটি ভালো পছন্দ। টাস্কটি সম্পূর্ণ হতে অনেক বেশি সময় লাগলে, ব্রাউজার সার্ভিস ওয়ার্কারকে বন্ধ করে দেবে, অন্যথায় এটি ব্যবহারকারীর গোপনীয়তা ও ব্যাটারির জন্য ঝুঁকিপূর্ণ হতে পারে।
Background Fetch API আপনাকে কোনও সার্ভিস ওয়ার্কারের মাধ্যমে দীর্ঘ টাস্ক অফলোড করার সুবিধা দেয়, যেমন সিনেমা, পডকাস্ট বা গেমের লেভেল ডাউনলোড করা।
পৃষ্ঠা থেকে সার্ভিস ওয়ার্কারের সাথে যোগাযোগ করতে, postMessage()-এর পরিবর্তে
backgroundFetch.fetch ব্যবহার করুন:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.fetch(
'my-fetch',
['/ep-5.mp3', 'ep-5-artwork.jpg'],
{
title: 'Episode 5: Interesting things.',
icons: [
{
sizes: '300x300',
src: '/ep-5-icon.png',
type: 'image/png',
},
],
downloadTotal: 60 * 1024 * 1024,
},
);
});
BackgroundFetchRegistration অবজেক্ট, পৃষ্ঠাটিকে progress ইভেন্ট শুনতে দেয় যাতে ডাউনলোডের প্রগ্রেস
ফলো করা যায়:
bgFetch.addEventListener('progress', () => {
// If we didn't provide a total, we can't provide a %.
if (!bgFetch.downloadTotal) return;
const percent = Math.round(
(bgFetch.downloaded / bgFetch.downloadTotal) * 100,
);
console.log(`Download progress: ${percent}%`);
});
পরবর্তী ধাপ
এই গাইডে আমরা পৃষ্ঠা ও সার্ভিস ওয়ার্কারের মধ্যে যোগাযোগের সবচেয়ে সাধারণ ক্ষেত্রটি এক্সপ্লোর করেছি (দ্বিমুখী যোগাযোগ)।
অনেক সময়, কোনও উত্তর না পেয়েও, অন্য ব্যক্তির সাথে যোগাযোগ করার জন্য একজনের শুধু একটি প্রসঙ্গ প্রয়োজন হতে পারে। ব্যবহারের উদাহরণ ও প্রোডাকশন উদাহরণ সহ, আপনার পৃষ্ঠায় সার্ভিস ওয়ার্কার থেকে এবং সার্ভিস ওয়ার্কার পর্যন্ত একমুখী টেকনিক কীভাবে প্রয়োগ করবেন সেই সম্পর্কে নির্দেশিকার জন্য নিম্নলিখিত গাইড দেখুন:
- ইম্পারেটিভ ক্যাশিং গাইড: রিসোর্স আগে থেকে ক্যাশে করার জন্য (যেমন, প্রিফেচিংয়ের ক্ষেত্রে) পৃষ্ঠা থেকে সার্ভিস ওয়ার্কারকে কল করা।
- ব্রডকাস্ট আপডেট: গুরুত্বপূর্ণ আপডেট (যেমন, ওয়েব অ্যাপের নতুন ভার্সন উপলভ্য) সম্পর্কে জানাতে সার্ভিস ওয়ার্কার থেকে পৃষ্ঠায় কল করা।