BroadcastChannel API - वेब के लिए मैसेज बस

एरिक बिडेलमैन

BroadcastChannel API से एक ही ऑरिजिन वाली स्क्रिप्ट को, अन्य ब्राउज़िंग कॉन्टेक्स्ट में मैसेज भेजने की अनुमति मिलती है. इसे एक सामान्य मैसेज बस के तौर पर माना जा सकता है, जो विंडो/टैब, iframe, वेब वर्कर, और सर्विस वर्कर के बीच पब/सब सिमैंटिक की अनुमति देता है.

API (एपीआई) की बुनियादी बातें

Broadcast Channel API एक आसान एपीआई है. इसकी मदद से, अलग-अलग ब्राउज़िंग कॉन्टेक्स्ट के बीच कम्यूनिकेट किया जा सकता है. इसका मतलब है, विंडो/टैब, iframes, वेब वर्कर, और सर्विस वर्कर के बीच बातचीत करना. किसी चैनल पर पोस्ट किए जाने वाले मैसेज, उस चैनल के सभी सुनने वालों को डिलीवर कर दिए जाते हैं.

BroadcastChannel कंस्ट्रक्टर एक पैरामीटर लेता है: चैनल का नाम. नाम से ही चैनल की पहचान होती है और यह सभी ब्राउज़िंग कॉन्टेक्स्ट में रहता है.

// Connect to the channel named "my_bus".
const channel = new BroadcastChannel('my_bus');

// Send a message on "my_bus".
channel.postMessage('This is a test message.');

// Listen for messages on "my_bus".
channel.onmessage = function(e) {
    console.log('Received', e.data);
};

// Close the channel when you're done.
channel.close();

मैसेज भेजें

मैसेज ऐसी स्ट्रिंग या कोई भी चीज़ हो सकती है जो स्ट्रक्चर्ड क्लोन एल्गोरिदम (स्ट्रिंग, ऑब्जेक्ट, सरणियों, ब्लॉब, अरे, अरे, मैप) के साथ काम करती हो.

उदाहरण - ब्लॉब या फ़ाइल भेजना

channel.postMessage(new Blob(['foo', 'bar'], {type: 'plain/text'}));

चैनल खुद पर ब्रॉडकास्ट नहीं होगा. इसलिए, अगर आपके पास एक ही चैनल के postMessage() वाले पेज पर, onmessage लिसनर है, तो message इवेंट ट्रिगर नहीं होगा.

अन्य तकनीकों से अंतर

अब आपके मन में यह जानने की इच्छा हो सकती है कि यह मैसेज पास करने की दूसरी तकनीकों से कैसे जुड़ी है, जैसे कि WebSockets, SharedWorker, MessageChannel API, और window.postMessage(). Broadcast Channel API इन एपीआई की जगह नहीं ले सकता. हर एक का एक मकसद होता है. Broadcast Channel API का मकसद, एक ही ऑरिजिन की स्क्रिप्ट के बीच वन-टू-मेनी कम्यूनिकेशन को आसान बनाना है.

ब्रॉडकास्ट चैनलों को इस्तेमाल करने के कुछ उदाहरण:

  • दूसरे टैब में उपयोगकर्ता की कार्रवाइयों का पता लगाएं
  • जब कोई उपयोगकर्ता किसी अन्य विंडो या टैब में, किसी खाते में लॉग इन करता है, तो इसकी जानकारी पाना.
  • किसी वर्कर को बैकग्राउंड में कुछ काम करने का निर्देश देना
  • कोई कार्रवाई पूरी हो जाने के बाद, उसकी सूचना पाएं.
  • जब उपयोगकर्ता एक विंडो में फ़ोटो अपलोड करता है, तो उसे खुले हुए दूसरे पेजों पर दिखाएं.

उदाहरण - वह पेज जिसे उपयोगकर्ता के लॉग आउट करने पर जानकारी मिलती है. यहां तक कि उसी साइट के किसी दूसरे खुले हुए टैब से भी लॉग आउट किया जाता है:

<button id="logout">Logout</button>

<script>
function doLogout() {
    // update the UI login state for this page.
}

const authChannel = new BroadcastChannel('auth');

const button = document.querySelector('#logout');
button.addEventListener('click', e => {
    // A channel won't broadcast to itself so we invoke doLogout()
    // manually on this page.
    doLogout();
    authChannel.postMessage({cmd: 'logout', user: 'Eric Bidelman'});
});

authChannel.onmessage = function(e) {
    if (e.data.cmd === 'logout') {
    doLogout();
    }
};
</script>

दूसरे उदाहरण में, मान लें कि जब उपयोगकर्ता आपके ऐप्लिकेशन में "ऑफ़लाइन स्टोरेज सेटिंग" बदल देता है, तो आपको सर्विस वर्कर को, कैश मेमोरी में सेव किया गया कॉन्टेंट हटाने का निर्देश देना था. window.caches का इस्तेमाल करके कैश मेमोरी मिटाई जा सकती है, लेकिन हो सकता है कि सर्विस वर्कर में पहले से ही कोई यूटिलिटी हो. हम उस कोड को फिर से इस्तेमाल करने के लिए Broadcast Channel API का इस्तेमाल कर सकते हैं! Broadcast Channel API के बिना, आपको self.clients.matchAll() के नतीजों को लूप करना होगा. साथ ही, हर क्लाइंट के लिए postMessage() को कॉल करना होगा, ताकि सर्विस वर्कर से उसके सभी क्लाइंट को संपर्क किया जा सके (ऐसा करने वाला असल कोड). ब्रॉडकास्ट चैनल का इस्तेमाल करने से, O(N) के बजाय O(1) हो जाता है.

उदाहरण - सर्विस वर्कर को कैश मेमोरी हटाने के लिए निर्देश दें. साथ ही, कंपनी के अंदरूनी इस्तेमाल के तरीकों का फिर से इस्तेमाल करके कैश मेमोरी को हटाने का अनुरोध करें.

index.html में

const channel = new BroadcastChannel('app-channel');
channel.onmessage = function(e) {
    if (e.data.action === 'clearcache') {
    console.log('Cache removed:', e.data.removed);
    }
};

const messageChannel = new MessageChannel();

// Send the service worker a message to clear the cache.
// We can't use a BroadcastChannel for this because the
// service worker may need to be woken up. MessageChannels do that.
navigator.serviceWorker.controller.postMessage({
    action: 'clearcache',
    cacheName: 'v1-cache'
}, [messageChannel.port2]);

sw.js में

function nukeCache(cacheName) {
    return caches.delete(cacheName).then(removed => {
    // ...do more stuff (internal) to this service worker...
    return removed;
    });
}

self.onmessage = function(e) {
    const action = e.data.action;
    const cacheName = e.data.cacheName;

    if (action === 'clearcache') {
    nukeCache(cacheName).then(removed => {
        // Send the main page a response via the BroadcastChannel API.
        // We could also use e.ports[0].postMessage(), but the benefit
        // of responding with the BroadcastChannel API is that other
        // subscribers may be listening.
        const channel = new BroadcastChannel('app-channel');
        channel.postMessage({action, removed});
    });
    }
};

postMessage() के साथ अंतर

postMessage() से अलग, अब आपको किसी iframe या वर्कर से संपर्क करने के लिए, उसका रेफ़रंस रखने की ज़रूरत नहीं होती:

// Don't have to save references to window objects.
const popup = window.open('https://another-origin.com', ...);
popup.postMessage('Sup popup!', 'https://another-origin.com');

window.postMessage() की मदद से, सभी ऑरिजिन से बातचीत की जा सकती है. Broadcast Channel API का ऑरिजिन एक ही है. यह ज़रूरी है कि मैसेज एक ही ऑरिजिन से आएं. इसलिए, उनकी पुष्टि करने की ज़रूरत नहीं है, जैसा कि हम window.postMessage() के साथ करते थे:

// Don't have to validate the origin of a message.
const iframe = document.querySelector('iframe');
iframe.contentWindow.onmessage = function(e) {
    if (e.origin !== 'https://expected-origin.com') {
    return;
    }
    e.source.postMessage('Ack!', e.origin);
};

किसी खास चैनल की "सदस्यता लें" और उनसे दोतरफ़ा बातचीत करें!

SharedWorker के साथ अंतर

ऐसे आसान मामलों के लिए BroadcastChannel का इस्तेमाल करें जहां आपको कई विंडो/टैब या वर्कर को मैसेज भेजने की ज़रूरत हो.

लॉक, शेयर की गई स्थिति को मैनेज करना, सर्वर और एक से ज़्यादा क्लाइंट के बीच संसाधनों को सिंक करना या रिमोट होस्ट के साथ WebSocket कनेक्शन शेयर करने जैसे आकर्षक इस्तेमाल के लिए, शेयर किए गए वर्कर सबसे सही समाधान हैं.

MessageChannel API के साथ अंतर

ChannelChannel Messages API और BroadcastChannel के बीच मुख्य अंतर यह है कि यह एक से ज़्यादा श्रोताओं (एक-से कई) तक मैसेज भेजने का ज़रिया है. MessageChannel को, स्क्रिप्ट के बीच सीधे तौर पर वन-टू-वन कम्यूनिकेशन के लिए बनाया गया है. इसमें और भी चीज़ें शामिल होती हैं, इसलिए आपको चैनल के हर सिरे पर पोर्ट के साथ चैनल सेटअप करने पड़ते हैं.

सुविधा की पहचान और ब्राउज़र सहायता

फ़िलहाल, Chrome 54, Firefox 38, और Opera 41 पर Broadcast Channel API काम करता है.

if ('BroadcastChannel' in self) {
    // BroadcastChannel API supported!
}

जहां तक पॉलीफ़िल की बात होती है, उनमें कुछ बातें होती हैं:

मैंने इन्हें नहीं आज़माया है, इसलिए आपका माइलेज अलग-अलग हो सकता है.

संसाधन