// import mqtt, { MqttClient } from 'mqtt'; import { Util } from '@/utils'; import { AccCentralMessage } from './message/acc-central-message'; import { AccSystemMessage } from './message/acc-system-message'; import { AccCurrentMessage } from './message/acc-current-message'; import { AppMessage } from './interface'; import { AccSendUtil } from './acc-send-util'; /** * App通讯中心 * * @export * @class CommunicationsCenter */ export class AppCommunicationsCenter { /** * 唯一实例 * * @private * @static * @type {AppCommunicationsCenter} * @memberof AppCommunicationsCenter */ private static readonly appCC: AppCommunicationsCenter = new AppCommunicationsCenter; /** * 应用中心消息 * * @private * @type {AccCentralMessage} * @memberof AppCommunicationsCenter */ private $accCentralMessage: AccCentralMessage = new AccCentralMessage(); /** * 发送消息工具 * * @type {AccSendUtil} * @memberof AppCommunicationsCenter */ public send: AccSendUtil = new AccSendUtil(this); /** * 应用中心级 * * @readonly * @type {AccCentralMessage} * @memberof AppCommunicationsCenter */ public get central(): AccCentralMessage { return this.$accCentralMessage; } /** * 系统消息 * * @private * @type {AccSystemMessage} * @memberof AppCommunicationsCenter */ private $accSystemMessage: AccSystemMessage = new AccSystemMessage(); /** * 系统级 * * @readonly * @type {AccSystemMessage} * @memberof AppCommunicationsCenter */ public get system(): AccSystemMessage { return this.$accSystemMessage; } /** * 当前页面消息 * * @private * @type {AccCurrentMessage} * @memberof AppCommunicationsCenter */ private $accCurrentMessage: AccCurrentMessage = new AccCurrentMessage(); /** * 页面级 * * @readonly * @type {AccCurrentMessage} * @memberof AppCommunicationsCenter */ public get current(): AccCurrentMessage { return this.$accCurrentMessage; } /** * 订阅缓存 * * @protected * @type {Map<string, string[]>} * @memberof AppCommunicationsCenter */ protected unsubscribeCache: Map<string, string[]> = new Map(); /** * 连接选项 * * @protected * @memberof AppCommunicationsCenter */ protected options = { // 超时时间 connectTimeout: 4000, // 认证信息 clientId: 'ws-' + new Date().getTime(), // username: 'emqx', // password: 'emqx', // 心跳时间 keepalive: 60, clean: true, } /** * 链接实例 * * @protected * @type {MqttClient} * @memberof AppCommunicationsCenter */ // protected ws!: MqttClient; /** * 连接地址 * * @protected * @type {string} * @memberof AppCommunicationsCenter */ protected url?: string; /** * 中心主题标识 * * @protected * @type {string} * @memberof AppCommunicationsCenter */ protected psdcconsoleid?: string; /** * 系统主题标识 * * @protected * @type {string} * @memberof AppCommunicationsCenter */ protected psdevslnsysid?: string; /** * 当前studio标识 * * @protected * @type {string} * @memberof AppCommunicationsCenter */ protected psdsconsoleid?: string; /** * Creates an instance of AppCommunicationsCenter. * @memberof AppCommunicationsCenter */ constructor(params?: { psdsconsoleurl: string, psdcconsoleid?: string, psdevslnsysid?: string, psdsconsoleid?: string }, opt: any = {}) { let me: any = this; if (AppCommunicationsCenter.appCC) { me = AppCommunicationsCenter.appCC; } // if (params) { // me.url = params.psdsconsoleurl; // me.psdcconsoleid = params.psdcconsoleid; // me.psdevslnsysid = params.psdevslnsysid; // me.psdsconsoleid = params.psdsconsoleid; // if (me.psdsconsoleid) { // me.options.clientId = me.psdsconsoleid; // } // Object.assign(me.options, opt); // if (me.url) { // if (me.ws) { // me.ws.disconnecting() // me.ws.disconnected(); // } // me.ws = mqtt.connect(me.url, this.options); // me.registerEvent(); // } // } return me; } /** * 注册事件 * * @protected * @memberof AppCommunicationsCenter */ protected registerEvent(): void { // this.ws.on('connect', () => { // // 订阅中心级 // if (this.psdcconsoleid) { // this.ws.subscribe(this.psdcconsoleid, { qos: 1 }, (error: any) => { // if (error) { // console.error('Central 订阅失败', error); // return; // } // }); // } // // 订阅系统级 // if (this.psdevslnsysid) { // this.ws.subscribe(this.psdevslnsysid, { qos: 1 }, (error: any) => { // if (error) { // console.error('System 订阅失败', error); // return; // } // }); // } // // 订阅当前级 // if (this.psdsconsoleid) { // this.ws.subscribe(this.psdsconsoleid, { qos: 1 }, (error: any) => { // if (error) { // console.error('Current 订阅失败', error); // return; // } // }); // } // }) // this.ws.on('reconnect', (error: any) => { // if (!error) { // console.log('正在重连...'); // } else { // console.warn('重连失败:', error); // } // }) // this.ws.on('error', (error: any) => { // console.log('连接失败:', error) // }) // this.ws.on('message', (topic: any, message: any) => { // let ms: string = ''; // try { // ms = message.toString('utf-8'); // const data: any = JSON.parse(ms); // switch (topic) { // case this.psdcconsoleid: // this.next('Central', data); // break; // case this.psdevslnsysid: // this.next('System', data); // break; // case this.psdsconsoleid: // this.next('Current', data); // break; // } // } catch (error) { // console.warn('消息中心:websocket消息解析失败!'); // console.warn('消息内容:', ms); // console.error(error); // } // }); } /** * 取消订阅 * * @param {string} key * @memberof AccMessage */ public unsubscribe(key: string): void { if (this.unsubscribeCache.has(key)) { const arr: any = this.unsubscribeCache.get(key); arr.forEach((str: string) => { this.unsubscribe(str); }); } else { this.$accCentralMessage.unsubscribe(key); this.$accSystemMessage.unsubscribe(key); this.$accCurrentMessage.unsubscribe(key); } } /** * 取消本地模式订阅 * * @param {string} key * @memberof AccMessage */ public unsubscribeLocal(key: string): void { if (this.unsubscribeCache.has(key)) { const arr: any = this.unsubscribeCache.get(key); arr.forEach((str: string) => { this.unsubscribeLocal(str); }); } else { this.$accCentralMessage.unsubscribeLocal(key); this.$accSystemMessage.unsubscribeLocal(key); this.$accCurrentMessage.unsubscribeLocal(key); } } /** * 发送消息 * * @param {('Central' | 'System' | 'Current')} type * @param {AppMessage} data * @memberof AppCommunicationsCenter */ public next(type: 'Central' | 'System' | 'Current', data: AppMessage) { switch (type) { case 'Central': this.$accCentralMessage.next(data); break; case 'System': this.$accSystemMessage.next(data); break; case 'Current': this.$accCurrentMessage.next(data); break; } } /** * 发送当前页面级消息 * * @param {AppMessage} message 消息内容 * @param {string} [deName] 消息对应的实体 * @memberof AppCommunicationsCenter */ public sendMessage(message: AppMessage, deName?: string) { const params: any = Util.deepCopy(message); const data: any = params.content; if (deName) { data.srfdename = deName; } else if ((!data.srfdename || Object.is(data.srfdename, '')) && data.srfdeid) { data.srfdename = data.srfdeid; } this.$accCurrentMessage.nextLocal(params); } /** * 订阅command * * @param {(content: any) => void} observer 回调函数 * @param {('update' | 'remove' | 'create')} [subtype] 更新类型 * @param {string} [deName] 实体名称 * @returns {string} * @memberof AppCommunicationsCenter */ public command(observer: (content: any) => void, subtype?: 'update' | 'remove' | 'create' | 'all', deName?: string): string { const arr: any[] = []; if (Object.is(subtype, 'update')) { arr.push(this.central.command.update.subscribe(observer, deName)); arr.push(this.system.command.update.subscribe(observer, deName)); arr.push(this.current.command.update.subscribe(observer, deName)); } else if (Object.is(subtype, 'remove')) { arr.push(this.central.command.remove.subscribe(observer, deName)); arr.push(this.system.command.remove.subscribe(observer, deName)); arr.push(this.current.command.remove.subscribe(observer, deName)); } else if (Object.is(subtype, 'create')) { arr.push(this.central.command.create.subscribe(observer, deName)); arr.push(this.system.command.create.subscribe(observer, deName)); arr.push(this.current.command.create.subscribe(observer, deName)); } else { arr.push(this.central.command.subscribe(observer, deName)); arr.push(this.system.command.subscribe(observer, deName)); arr.push(this.current.command.subscribe(observer, deName)); } const key: string = this.createUUID(); this.unsubscribeCache.set(key, arr); return key; } /** * 订阅command * * @param {(content: any) => void} observer 回调函数 * @param {('update' | 'remove' | 'create')} [subtype] 更新类型 * @param {string} [deName] 实体名称 * @returns {string} * @memberof AppCommunicationsCenter */ public commandLocal(observer: (content: any) => void, subtype?: 'update' | 'remove' | 'create' | 'all', deName?: string): string { const arr: any[] = []; if (Object.is(subtype, 'update')) { arr.push(this.current.command.update.subscribeLocal(observer, deName)); } else if (Object.is(subtype, 'remove')) { arr.push(this.current.command.remove.subscribeLocal(observer, deName)); } else if (Object.is(subtype, 'create')) { arr.push(this.current.command.create.subscribeLocal(observer, deName)); } else { arr.push(this.current.command.subscribeLocal(observer, deName)); } const key: string = this.createUUID(); this.unsubscribeCache.set(key, arr); return key; } /** * 订阅console * * @param {(content: any) => void} observer * @returns {string} * @memberof AppCommunicationsCenter */ public console(observer: (content: any) => void): string { const arr: any[] = []; arr.push(this.central.console.subscribe(observer)); arr.push(this.system.console.subscribe(observer)); arr.push(this.current.console.subscribe(observer)); const key: string = this.createUUID(); this.unsubscribeCache.set(key, arr); return key; } /** * 订阅console本地消息 * * @param {(content: any) => void} observer * @returns {string} * @memberof AppCommunicationsCenter */ public consoleLocal(observer: (content: any) => void): string { const key: string = this.createUUID(); this.unsubscribeCache.set(key, [this.current.console.subscribeLocal(observer)]); return key; } /** * 获取实例 * * @static * @returns * @memberof AppCommunicationsCenter */ public static getInstance() { return AppCommunicationsCenter.appCC; } /** * 创建 UUID * * @returns {string} * @memberof Util */ protected createUUID(): string { function s4() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } } /** * 应用通讯中心实例 */ export const acc = AppCommunicationsCenter.getInstance();