封装broadcastchannel,支持跨标签通信、多订阅模式、自动重连和错误处理

1.创建broadcast channel的js文件:

class ChannelManager {
  /**
   * 创建频道管理器
   * @param {string} channelName - 频道名称(需保证同源页面使用相同名称)
   * @param {object} [options] - 配置选项
   * @param {boolean} [options.autoReconnect=true] - 是否自动重连:ml-citation{ref="1,5" data="citationList"}
   */
  constructor(channelName, options = {}) {
    this.channelName = channelName;
    this.options = { autoReconnect: true, ...options };
    this._initChannel();
    this._messageHandlers = new Set();
  }

  // 初始化频道连接
  _initChannel() {
    this.channel = new BroadcastChannel(this.channelName);
    
    // 消息监听
    this.channel.onmessage = (event) => {
      this._messageHandlers.forEach(handler => handler(event.data));
    };

    // 错误处理:ml-citation{ref="1,3" data="citationList"}
    this.channel.onmessageerror = (error) => {
      console.error('消息解析失败:', error);
      this.close();
      if (this.options.autoReconnect) this._initChannel();
    };

    this.channel.addEventListener('close', () => {
      if (this.options.autoReconnect) this._initChannel();
    });
  }

  /**
   * 发送消息
   * @param {any} data - 可序列化的任意类型数据:ml-citation{ref="5" data="citationList"}
   */
  send(data) {
    if (this.channel) this.channel.postMessage(data);
  }

  /**
   * 订阅消息
   * @param {function} handler - 消息处理函数
   * @returns {function} 取消订阅函数
   */
  subscribe(handler) {
    this._messageHandlers.add(handler);
    return () => this.unsubscribe(handler);
  }

  // 取消订阅
  unsubscribe(handler) {
    this._messageHandlers.delete(handler);
  }

  // 关闭频道:ml-citation{ref="1,5" data="citationList"}
  close() {
    if (this.channel) {
      this.channel.close();
      this._messageHandlers.clear();
      this.channel = null;
    }
  }
}

  1. 使用
// 创建频道实例
const chatChannel = new ChannelManager('chat_room');

// 订阅消息
const unsubscribe = chatChannel.subscribe(data => {
  console.log('收到消息:', data);
});

// 发送消息
chatChannel.send({ user: 'Alice', text: 'Hello!' });

// 关闭频道(切换页面时建议调用)
 chatChannel.close()
// window.addEventListener('beforeunload', () => chatChannel.close());
//vue: beforeDestory中调用chatChannel.unsubscribe 和chatChannel.close方法,react:useEffect(()=>{ return=>(调用chatChannel.unsubscribe 和chatChannel.close方法)},[])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容