import socket from '@ohos.net.socket' import { UDPTag } from '../config' import { FillZero, StringToASCII } from './Common' import { BusinessError } from '@ohos.base' import { dConsole } from './LogWorker' interface MsgExt { id: number, list: number[], carNo: string, placeId: string, } function generateHead(param: MsgExt): number[] { let lshNo = AppStorage.get("lsh") let a = new Uint16Array(StringToASCII(`${param.id}${FillZero(param.placeId, 3)}`)) let b = new Uint32Array(StringToASCII(`${FillZero(param.carNo, 4)}${lshNo}`)) let c = new Uint16Array(param.list.length) return [...a, ...b, ...c]; } function exclusive(target: number[]): number[] { let result = target[0] for (let i = 1; i < target.length; i++) { result = result ^ target[i] } return [result]; } type DealMethod = (value: ArrayBuffer) => T export default class UdpClient { protected udp: socket.UDPSocket | null = null private localIp: string = '' private localIpPort: string = '' private oppositeIp: string = '' private oppositeIpPort: string = '' private messageEvents: Array = [] private errorEvents: Array = [] private dealMethod?: DealMethod // 连接状态 private linkStatus: boolean = false // 绑定udp连接 bindUdp(): Promise | undefined { console.log(UDPTag, "绑定udp", this.localIp, this.localIpPort) return this.udp?.bind({ address: this.localIp, port: parseInt(this.localIpPort), family: 1 }).then(res => { console.log(UDPTag, "udp 绑定成功!", JSON.stringify(res)) }) } // 重新绑定udp连接 async reBind() { await this.close() this.udp = socket.constructUDPSocketInstance(); this.bindEvent() await this.bindUdp() } // 关闭udp连接 close(): Promise | undefined { this.messageEvents = [] this.errorEvents = [] this.dealMethod = undefined this.udp?.off("message") this.udp?.off("error") return this.udp?.close() } // 设置处理消息的函数 setDealMethod(fun: DealMethod) { this.dealMethod = fun } // 发送消息 sendMsg(data: ArrayBuffer | string): Promise | undefined { return this.udp?.send({ data, address: { address: this.oppositeIp, port: parseInt(this.oppositeIpPort), family: 1 } }).then(res => { // console.log(UDPTag, "udp发送成功", JSON.stringify(res)) }).catch((e: BusinessError) => { console.error(UDPTag, "udp发送失败", JSON.stringify(e)) }) } // 组装消息 setWholeMsg(params: MsgExt): ArrayBuffer { let head = generateHead(params); let headJudge = exclusive(head); let body = params.list; let bodyJudge = exclusive(body); let end = [13, 10]; const arr = [...head, ...headJudge, ...body, ...bodyJudge, ...end] return new Uint8Array(arr).buffer } // 发送消息 sendMsgExt(param: MsgExt) { dConsole.info(UDPTag, "小红球数据", param) const msgData = this.setWholeMsg(param) this.sendMsg(msgData) } // 创建udp实例 async create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) { console.log(UDPTag, "udp 初始化参数", udpLocalIp, udpLocalIpPort, udpOppositeIp, udpOppositeIpPort) await this.close() this.localIp = udpLocalIp this.oppositeIp = udpOppositeIp this.localIpPort = udpLocalIpPort this.oppositeIpPort = udpOppositeIpPort try { this.udp = socket.constructUDPSocketInstance(); this.bindUdp() this.bindEvent() } catch (e) { console.log(UDPTag, "udp错误", JSON.stringify(e)) } } // 绑定消息事件 onMsg(callback: Function) { if (this.messageEvents.findIndex(cb => cb === callback) !== -1) { return } this.messageEvents.push(callback) } // 绑定错误事件 onError(callback: Function) { this.errorEvents.push(callback) } // 取消绑定事件 offMsg(callback: Function) { this.messageEvents = this.messageEvents.filter(cb => cb !== callback) } // 绑定事件 private bindEvent() { this.udp?.on("message", value => { let result = this.dealMethod?.(value.message) // console.log(UDPTag, "udp获取消息", result) this.messageEvents.forEach(cb => { cb(result) }) }) this.udp?.on("error", (err) => { console.log(UDPTag, 'udp error', JSON.stringify(err)) this.errorEvents.forEach(cb => { cb(err) }) }) } }