Cross-Context Communication in BroadcastChannel API
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.
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.
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.
【Cross-Context Communication in BroadcastChannel API】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
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.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.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/bro...). 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.window.addEventListener('storage', (evt) => {
if (evt.key == 'myname') {
console.log(evt.newValue)
}
})localStorage.setItem('myname', 'hi')
推荐阅读
- 使用homeBrew|使用homeBrew 安装Goland
- Android|Android Studio 的 Browse Repositories 下载不了插件
- Kotlin学习笔记——BroadCast
- 读书笔记-健身入门
- Git|Git branching strategy integated with testing/QA process - Stack Overflow
- IDEA2019.3激活|IDEA2019.3激活 Jetbrains全系列激活
- Bruce投资课学习笔记
- MySql与数据库设计规范
- mac|mac 配置nginx 虚拟站点
- 第十九周打卡总结(break|第十九周打卡总结(break 2)