同源多页面实时通信之BroadcastChannel实现及简单封装

news/2024/7/5 3:17:31

目录

  • 背景
  • 介绍及API使用
    • 是什么
    • 对象实例化
    • 发送消息
    • 监听消息
    • 错误处理
    • 关闭通道
  • 项目中简单封装
    • channel.js文件,引入到使用的页面中
    • 发送端send.html
    • 监听端
    • 运行测试一下吧
  • 浏览器兼容程度
  • 总结

背景

日常开发做项目时,如果采用非Vue脚手架时,肯定会碰到这样的场景:比如在浏览器中新开两个tab页面,A页面发送消息后,B页面实时监听并触发某些动作。类似的需求有很多,比如实时共享状态等等。这样的实时通信场景的解决方案我相信大家有很多想法,比如localStoragepostMessageWebSocketsharedWorker等等。
今天带来另一种方式:BroadcastChannel广播通信。如果着急,可直接跳转到“项目中简单封装章节查看封装代码”

介绍及API使用

是什么

BroadcastChannel 接口代理了一个命名频道,可以让指定 origin 下的任意 browsing context 来订阅它。它允许同源的不同浏览器窗口,Tab 页,frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件,消息可以广播到所有监听了该频道的 BroadcastChannel 对象。

简单来说,就是需要在同源的情况下,实现浏览器多窗口实时进行通信,且该通信是广播进行的。

对象实例化

// 通道名称,用以区分不同的通道。对于相同的来源下的所有浏览上下文,一个名称只对应一个通道。是string类型,用来标识当前的BroadcastChannel
const channel = new BroadcastChannel(channelName)

发送消息

可以使用postMessage() 发送一条消息,给所有同源下监听了该频道的所有浏览器。消息message事件的形式发送给每一个绑定到该频道的广播频道。

 
const channel = new BroadcastChannel("test")
 
// 发送消息通知,参数是任何对象
bc.postMessage('hello xiaozong');

监听消息

发送事件后,如何使用进行消息的监听呢?当频道收到一条消息时,会在关联的BroadcastChannel对象上触发 message 事件,监听方式有两种,具体如下:

const channel = new BroadcastChannel("test")
// 消息监听 方式一
channel.onmessage = ({data}) => {
	// 这里写具体的业务逻辑
}
 
// 消息监听 方式二
channel.addEventListener('message', ({data}) => {
	// 这里写具体的业务逻辑
})

错误处理

const channel = new BroadcastChannel('test');
 
// 方式一
channel.addEventListener('messageerror', ({data}) => {
  console.error(data);
})
 
// 方式二
channel.onmessageerror = ({data}) => {
  console.log(data);
};

关闭通道

通过调用 close() 方法,可以马上断开其与对应频道的关联,并让其被垃圾回收。这是必要的步骤,因为浏览器没有其他方式知道频道不再被需要。不断开可能会导致一直处于监听状态,消耗资源,会导致不能被内存回收。

// 连接到指定频道
const channel = new BroadcastChannel('test');

// 当完成后,断开与频道的连接
channel.close();

项目中简单封装

channel.js文件,引入到使用的页面中

/**
 * 简单封装BroadcastChannel的用法
 */
const Channel = {
    /**
     * BroadcastChannel对象
     */
    channel: null,

    /**
     * 实例化BroadcastChannel对象,赋值给channel变量
     * @param {*} channelName 通道名称,用以区分不同的通道
     * @returns 
     */
    getChannel: (channelName) => {
        Channel.channel = new BroadcastChannel(channelName)
        return Channel.channel
    },

    /**
     * 发送消息
     * @param {*} object 消息体
     */
    send: (object) => {
        Channel.channel.postMessage(object)
    },

    /**
     * 发送消息,重载方法,可直接调用,省略对象实例化操作
     * @param {*} channelName 通道名称,用以区分不同的通道
     * @param {*} object 消息体
     */
    send: (channelName, object) => {
        if (Channel.channel == null) {
            Channel.channel = Channel.getChannel(channelName)
        }
        Channel.channel.postMessage(object)
    },

    /**
     * 监听消息
     * @param {*} callback 回调函数
     */
    listen: (callback) => {
        Channel.channel.onmessage = ({ data }) => {
            callback(data)
        }
    },

    /**
     * 监听消息,重载方法,可直接调用,省略对象实例化操作
     * @param {*} channelName 通道名称,用以区分不同的通道
     * @param {*} callback 回调函数
     */
    listen: (channelName, callback) => {
        if (Channel.channel == null) {
            Channel.channel = Channel.getChannel(channelName)
        }
        Channel.channel.onmessage = ({ data }) => {
            callback(data)
        }
    },

    /**
     * 通道关闭
     */
    close: () => {
        Channel.channel.close()
    },

    /**
     * 通道关闭,重载方法,可直接调用,省略对象实例化操作
     * @param {*} channelName 通道名称,用以区分不同的通道
     */
    close: (channelName) => {
        if (Channel.channel == null) {
            Channel.channel = Channel.getChannel(channelName)
        }
        Channel.channel.close()
    },

    /**
     * 通道枚举,定义业务中需要用到的所有通道名称枚举,可根据业务需求无限扩容
     */
    channelEnum: {
        TEST: { name: 'test', coment: '测试通道' },
        REAL_EVENT: { name: 'real_event', coment: '实时事项通道' },
    }
}

发送端send.html

使用方式测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>标签页通信-发送端</title>
    <script src="./channel.js"></script>
</head>

<body>
    标签页通信-发送端
</body>
<script>
    Channel.send(Channel.channelEnum.TEST.name, 'hello xiaozong')

</script>

</html>

监听端

使用方式测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>标签页通信-接收端</title>
    <script src="./channel.js"></script>
</head>

<body>
    标签页通信-接收端
</body>
<script>
    Channel.listen(Channel.channelEnum.TEST.name, (data) => {
        document.write(`<p>${data}</p>`)
    })
</script>

</html>

运行测试一下吧

就只贴一下图吧 ,比较简单
在这里插入图片描述
在这里插入图片描述

浏览器兼容程度

在这里插入图片描述

总结

昨晚十二点左右心血来潮,太晚了也只进行了简单的封装,基本满足常规场景的使用,如果实际项目开发中有用到的话,可以优化后使用。


http://lihuaxi.xjx100.cn/news/1617443.html

相关文章

【从0开发】百度BML全功能AI开发平台【实操:以部署情感分析模型为例】

目录 一、全功能AI开发平台介绍二、AI项目落地应用流程&#xff08;以文本分类为例&#xff09;2-0、项目开始2-1、项目背景2-2、数据准备介绍2-3、项目数据2-4、建模调参介绍2-5、项目的建模调参2-6、开发部署2-7、项目在公有云的部署 附录&#xff1a;调用api代码总结 一、全…

2023年中国尾气净化催化材料产量、需求量及行业市场规模分析[图]

尾气处理催化单元系由催化剂厂商将以催化材料和活性组分物质为主要组成的催化剂涂覆在蜂窝陶瓷或金属等载体上而成&#xff0c;催化剂则起到处理尾气中有害物质的各类化学反应的关键催化作用&#xff0c;主要由稀土材料、氧化铝材料、贵金属材料等催化材料和增强催化材料性能的…

网站列表页加密:三次请求后返回内容多\r

一、抓包第一次请求 url aHR0cDovL2N5eHcuY24vQ29sdW1uLmFzcHg/Y29saWQ9MTA抓包&#xff0c;需要清理浏览器cookie&#xff0c;或者无痕模式打开网址&#xff0c;否则返回的包不全&#xff0c;依照下图中的第一个包进行requests请求 第一次请求后返回 <!DOCTYPE html>…

2023年中国印花布产量及发展前景分析:数码印花将成为行业趋势[图]

印花布是用坯布印花纸高温印染加工而成&#xff0c;唐宋时期已很盛行&#xff0c;明清时期达到鼎盛。曾深受人们的喜爱&#xff0c;被作为陪嫁被褥、衣服的必备品。印花布上的图案称作花型&#xff0c;瓦栏、花型创意分享平台。 印花布种类 资料来源&#xff1a;共研产业咨询&…

第五十六章 学习常用技能 - 执行 SQL 查询

文章目录 第五十六章 学习常用技能 - 执行 SQL 查询执行 SQL 查询检查对象属性 第五十六章 学习常用技能 - 执行 SQL 查询 执行 SQL 查询 要运行 SQL 查询&#xff0c;请在管理门户中执行以下操作&#xff1a; 选择系统资源管理器 > SQL。如果需要&#xff0c;请选择标题…

【AI视野·今日NLP 自然语言处理论文速览 第五十二期】Wed, 11 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 11 Oct 2023 Totally 81 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers LongLLMLingua: Accelerating and Enhancing LLMs in Long Context Scenarios via Prompt Compression Author…

2023年中国光纤传感器发展历程、需求量及行业市场规模分析[图]

光纤传感器是利用光纤作为媒介&#xff0c;将外界温度、应变等被测量转化为光纤中传输的光波的强度、相位、频率、波长、偏振态等光学信息的部件。光纤传感器由光源、入射光纤、出射光纤、光调制器、光探测器及解调器组成。其基本原理是将光源的光经入射光纤送入调制区&#xf…

【数值分析】0 - 数值分析绪论

文章目录 一、数值分析介绍二、数值分析应用2.1 解三角函数2.2 计算多项式2.3 解线性方程组2.4 供水计划和生产调度计划的制定2.5 湘江水流量估计的实际意义2.6 机器学习或大数据 三、数值分析内容四、数值分析参考书目 学习视频&#xff1a;《数值分析》| 华科 | 研究生基础课…