1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ciimport { Utils, MessageParam } from "./Util" 16fb726d48Sopenharmony_ciimport { Constants, TypeConstants } from "./Constants"; 17fb726d48Sopenharmony_ci 18fb726d48Sopenharmony_ciexport class WebSocketManager { 19fb726d48Sopenharmony_ci static instance: WebSocketManager | null | undefined = null; 20fb726d48Sopenharmony_ci url: string = 'ws://localhost:18080';//8080后期需要修改 21fb726d48Sopenharmony_ci private websocket: WebSocket | null | undefined = null; 22fb726d48Sopenharmony_ci private ready: boolean = false; 23fb726d48Sopenharmony_ci private distributeMap: Map<number, Function> = new Map<number, Function>(); 24fb726d48Sopenharmony_ci private sessionId: number | null | undefined; 25fb726d48Sopenharmony_ci private session: bigint | null | undefined; 26fb726d48Sopenharmony_ci private heartbeatInterval: number | null | undefined; 27fb726d48Sopenharmony_ci 28fb726d48Sopenharmony_ci constructor() { 29fb726d48Sopenharmony_ci if (WebSocketManager.instance) { 30fb726d48Sopenharmony_ci return WebSocketManager.instance; 31fb726d48Sopenharmony_ci } 32fb726d48Sopenharmony_ci WebSocketManager.instance = this; 33fb726d48Sopenharmony_ci //连接websocket 34fb726d48Sopenharmony_ci this.connectWebSocket(); 35fb726d48Sopenharmony_ci } 36fb726d48Sopenharmony_ci //连接WebSocket 37fb726d48Sopenharmony_ci connectWebSocket(): void { 38fb726d48Sopenharmony_ci this.websocket = new WebSocket(this.url); 39fb726d48Sopenharmony_ci this.websocket.binaryType = "arraybuffer"; 40fb726d48Sopenharmony_ci this.websocket.onopen = () => { 41fb726d48Sopenharmony_ci // 设置心跳定时器 42fb726d48Sopenharmony_ci this.sendHeartbeat(); 43fb726d48Sopenharmony_ci // 连接后登录 44fb726d48Sopenharmony_ci this.login(); 45fb726d48Sopenharmony_ci }; 46fb726d48Sopenharmony_ci 47fb726d48Sopenharmony_ci //接受webSocket的消息 48fb726d48Sopenharmony_ci this.websocket.onmessage = (event) => { 49fb726d48Sopenharmony_ci // 先解码 50fb726d48Sopenharmony_ci let decode: MessageParam = Utils.decode(event.data); 51fb726d48Sopenharmony_ci if (decode.type === TypeConstants.HEARTBEAT_TYPE) { 52fb726d48Sopenharmony_ci return; 53fb726d48Sopenharmony_ci } 54fb726d48Sopenharmony_ci this.onmessage(decode!); 55fb726d48Sopenharmony_ci }; 56fb726d48Sopenharmony_ci 57fb726d48Sopenharmony_ci this.websocket.onerror = (error) => { 58fb726d48Sopenharmony_ci console.error('error:', error); 59fb726d48Sopenharmony_ci }; 60fb726d48Sopenharmony_ci 61fb726d48Sopenharmony_ci this.websocket.onclose = (event) => { 62fb726d48Sopenharmony_ci this.initLoginInfor(); 63fb726d48Sopenharmony_ci this.clearHeartbeat(); 64fb726d48Sopenharmony_ci this.reconnect(event); 65fb726d48Sopenharmony_ci }; 66fb726d48Sopenharmony_ci } 67fb726d48Sopenharmony_ci 68fb726d48Sopenharmony_ci /** 69fb726d48Sopenharmony_ci * 接收webSocket返回的buffer数据 70fb726d48Sopenharmony_ci * 分别处理登录、其他业务的数据 71fb726d48Sopenharmony_ci * 其他业务数据分发 72fb726d48Sopenharmony_ci */ 73fb726d48Sopenharmony_ci onmessage(decode: MessageParam): void { 74fb726d48Sopenharmony_ci // 解码event 调decode 75fb726d48Sopenharmony_ci if (decode.type === TypeConstants.LOGIN_TYPE) {// 登录 76fb726d48Sopenharmony_ci if (decode.cmd === Constants.LOGIN_CMD) { 77fb726d48Sopenharmony_ci this.ready = true; 78fb726d48Sopenharmony_ci this.sessionId = decode.session_id; 79fb726d48Sopenharmony_ci this.session = decode.session; 80fb726d48Sopenharmony_ci } 81fb726d48Sopenharmony_ci } else {// type其他 82fb726d48Sopenharmony_ci for (let [key, callback] of this.distributeMap.entries()) { 83fb726d48Sopenharmony_ci if (key === decode.type) { 84fb726d48Sopenharmony_ci callback(decode.cmd, decode.data); 85fb726d48Sopenharmony_ci } 86fb726d48Sopenharmony_ci }; 87fb726d48Sopenharmony_ci } 88fb726d48Sopenharmony_ci } 89fb726d48Sopenharmony_ci 90fb726d48Sopenharmony_ci // 登录 91fb726d48Sopenharmony_ci login(): void { 92fb726d48Sopenharmony_ci this.websocket!.send(Utils.encode(Constants.LOGIN_PARAM)); 93fb726d48Sopenharmony_ci } 94fb726d48Sopenharmony_ci 95fb726d48Sopenharmony_ci // 模块调 96fb726d48Sopenharmony_ci static getInstance(): WebSocketManager | null | undefined { 97fb726d48Sopenharmony_ci if (!WebSocketManager.instance) { 98fb726d48Sopenharmony_ci new WebSocketManager(); 99fb726d48Sopenharmony_ci } 100fb726d48Sopenharmony_ci return WebSocketManager.instance 101fb726d48Sopenharmony_ci } 102fb726d48Sopenharmony_ci 103fb726d48Sopenharmony_ci // WebSocket是否登录成功 104fb726d48Sopenharmony_ci isReady(): boolean { 105fb726d48Sopenharmony_ci return this.ready 106fb726d48Sopenharmony_ci } 107fb726d48Sopenharmony_ci 108fb726d48Sopenharmony_ci /** 109fb726d48Sopenharmony_ci * 消息监听器 110fb726d48Sopenharmony_ci * listener是不同模块传来接收数据的函数 111fb726d48Sopenharmony_ci * 模块调用 112fb726d48Sopenharmony_ci */ 113fb726d48Sopenharmony_ci registerMessageListener(type: number, callback: Function): void { 114fb726d48Sopenharmony_ci if (!this.distributeMap.has(type)) { 115fb726d48Sopenharmony_ci this.distributeMap.set(type, callback); 116fb726d48Sopenharmony_ci } 117fb726d48Sopenharmony_ci } 118fb726d48Sopenharmony_ci 119fb726d48Sopenharmony_ci /** 120fb726d48Sopenharmony_ci * 传递数据信息至webSocket 121fb726d48Sopenharmony_ci * 模块调 122fb726d48Sopenharmony_ci */ 123fb726d48Sopenharmony_ci sendMessage(type: number, cmd?: number, data?: Uint8Array): void { 124fb726d48Sopenharmony_ci // 检查WebSocket是否登录成功 125fb726d48Sopenharmony_ci if (!this.ready) {// 改判断条件 ready 126fb726d48Sopenharmony_ci return; 127fb726d48Sopenharmony_ci } 128fb726d48Sopenharmony_ci let message: MessageParam = { 129fb726d48Sopenharmony_ci type: type, 130fb726d48Sopenharmony_ci cmd: cmd, 131fb726d48Sopenharmony_ci session_id: this.sessionId!, 132fb726d48Sopenharmony_ci session: this.session!, 133fb726d48Sopenharmony_ci data_lenght: data ? data.byteLength : undefined, 134fb726d48Sopenharmony_ci data: data 135fb726d48Sopenharmony_ci } 136fb726d48Sopenharmony_ci let encode = Utils.encode(message); 137fb726d48Sopenharmony_ci this.websocket!.send(encode!); 138fb726d48Sopenharmony_ci } 139fb726d48Sopenharmony_ci 140fb726d48Sopenharmony_ci /** 141fb726d48Sopenharmony_ci * 传递数据信息至webSocket 142fb726d48Sopenharmony_ci * 模块调 143fb726d48Sopenharmony_ci */ 144fb726d48Sopenharmony_ci reconnect(event: unknown) { 145fb726d48Sopenharmony_ci //@ts-ignore 146fb726d48Sopenharmony_ci if (event.wasClean) {// 正常关闭 147fb726d48Sopenharmony_ci return 148fb726d48Sopenharmony_ci } 149fb726d48Sopenharmony_ci // 未连接成功打开定时器 150fb726d48Sopenharmony_ci setTimeout(() => { 151fb726d48Sopenharmony_ci this.connectWebSocket(); 152fb726d48Sopenharmony_ci }, Constants.INTERVAL_TIME) 153fb726d48Sopenharmony_ci } 154fb726d48Sopenharmony_ci 155fb726d48Sopenharmony_ci // 定时检查心跳 156fb726d48Sopenharmony_ci sendHeartbeat() { 157fb726d48Sopenharmony_ci this.heartbeatInterval = window.setInterval(() => { 158fb726d48Sopenharmony_ci this.sendMessage(TypeConstants.HEARTBEAT_TYPE) 159fb726d48Sopenharmony_ci }, Constants.INTERVAL_TIME) 160fb726d48Sopenharmony_ci } 161fb726d48Sopenharmony_ci 162fb726d48Sopenharmony_ci /** 163fb726d48Sopenharmony_ci * 重连时初始化登录信息 164fb726d48Sopenharmony_ci * 在异常关闭时调用 165fb726d48Sopenharmony_ci */ 166fb726d48Sopenharmony_ci initLoginInfor() { 167fb726d48Sopenharmony_ci this.ready = false; 168fb726d48Sopenharmony_ci this.sessionId = null; 169fb726d48Sopenharmony_ci this.session = null; 170fb726d48Sopenharmony_ci } 171fb726d48Sopenharmony_ci 172fb726d48Sopenharmony_ci // 连接关闭时,清除心跳 173fb726d48Sopenharmony_ci clearHeartbeat() { 174fb726d48Sopenharmony_ci if (this.heartbeatInterval) { 175fb726d48Sopenharmony_ci clearInterval(this.heartbeatInterval); 176fb726d48Sopenharmony_ci this.heartbeatInterval = null; 177fb726d48Sopenharmony_ci } 178fb726d48Sopenharmony_ci } 179fb726d48Sopenharmony_ci} 180