前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Cross-Context Communication in BroadcastChannel API

Cross-Context Communication in BroadcastChannel API

作者头像
^_^肥仔John
发布2021-09-29 15:10:00
3700
发布2021-09-29 15:10:00
举报

The broadcast channel API allows basically communication between browsing contexts(that is, tabs, windows, frames or iframes) and workers on the same origin. You don't have to maintain the reference to the frames or workers you wish to communicate with, just constructing your own BroadcastChannel instance with the channel name which is capable of bidirectional communication between all of them.

It's self-contained interface and allows cross-context communication, what a perfect solution to detect user actions in other tabs within the same origin, like when user logs in or out, to transmit data across them and keep the states in sync. That's of great benefit to multiple tabs apps.

Scenario: log in status

It's a way common feature to show the log in status after user pass authentication and walk around, and open the other tabs to log out. But he or she is still in logged in status on the first tab, which will make user confused, until anything he or she touch will either redirect to the login page or straight blow up in their face. A more inviting alternative is to figure out that they've logged out and do something about it, like, display a hint to asking them to log in again.

代码语言:javascript
复制
let loginStatus = 'login', originalLoginStatus = 'login'
window.addEventListener('focus', () => {
    if (loginStatus !== originalLoginStatus) {
        alert('You have logged out on other tab already!')
        location.reload()
    }
})

const bc = new BroadcastChannel('login-status')
bc.onmessage = evt => {
    loginStatus = evt.data
}

document.querySelector('#logout').addEventListener('click', () => {
    bc.postMessage('logout')
})

Creating or Joining a Channel

To their credit, the form of creating a channel is identical to that of joining, it means the new channel would be created automatically for us if it isn't existing yet. So there is no more simple to do like below.

代码语言:javascript
复制
const channelName = 'update'
const bc = new BroadcastChannel(channelName)

Sending Messages

It's enough to call the postMessage method on the created BroadcastChannel instance with an argument for any types.

Note that this API doesn't associate any sematics(messaging protocol) to messages (there is no negotiation nor requirement from specifcation), it's all up to you to know what kind of messages to expect and what to do with them.

And what exactly types could we pass in? The answer is all types that can be cloned using the structured clone algorithm, including the followings:

  • All primitive types except symbol(boolean, string, number, null, undefined)
  • Dates
  • Regular Expressions
  • Blobs
  • Files and FileLists
  • ArrayBuffers and ArrayBufferViews
  • ImageBitmaps, ImageDatas
  • Boolean, Number, Arrays, Objects, Maps and Sets
代码语言:javascript
复制
br.postMessage('hi')

Receiving Messages

Once a message is posted, a message event will be dispatched to the BroadcastChannel instance connected to this channel. And the event handler binding by onmessage method on the created BroadcastChannel object will be run.

代码语言:javascript
复制
br.onmessage = evt => {
    const message = evt.data
    // processing
}

Disconnecting a Channel

It might make sense to call close method on the BroadcastChannel object when we do not use it anymore, this would disconnect the object from the underlying channel, and once there is no references to that channel any longer, allowing garbage collection.

代码语言:javascript
复制
br.close()

Compatiblity

This API has landed in Chrome years ago, but if you have to make your app work on the legacy browser, to my knowledge, the most popular one is here(https://github.com/pubkey/broadcast-channel). You can use it almost exactly like the native API. It will switch up to the native API automatically if supporting for the more efficient result, otherwise, it will utilize IndexedDB or LocalStorage. We can register storage event on window object to detect any changes(additions, updates and deletions) of value on LocalStorage.

代码语言:javascript
复制
window.addEventListener('storage', (evt) => {
    if (evt.key == 'myname') {
        console.log(evt.newValue)
    }
})

localStorage.setItem('myname', 'hi')
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-09-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Scenario: log in status
  • Creating or Joining a Channel
  • Sending Messages
  • Receiving Messages
  • Disconnecting a Channel
  • Compatiblity
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档