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;
}
}
}
- 使用
// 创建频道实例
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方法)},[])