/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // @ts-ignore import socket, { UDPSocket } from '@ohos.net.socket'; import { Array2Byte } from '../utils/tools' import FileUtil from '../../common/utils/File' import { fillZero, string2Bytes } from '../utils/tools' const TAG = '[UdpDemo.UdpClient]' import hilog from '@ohos.hilog'; import prompt from '@ohos.prompt' export default class UdpClientByCenter { private localIp: string = '' private localIpPort: string = '' private oppositeIp: string = '' private oppositeIpPort: string = '' private udpMsg: any = '' private num: number = 0 private fileUtil: FileUtil private udp: UDPSocket = null private sendId: any = 0 private lsh: string = null private context private stashFn: StashFunction private headLenth: number = 9 //消息头长度 private isWorking: Boolean = false private plcUdpError = false; private initParam private onMessage_1Callback:Function = ()=>{} public currentValue:string = '' constructor(udplocalIp: string, udplocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) { this.localIp = udplocalIp this.oppositeIp = udpOppositeIp this.localIpPort = udplocalIpPort this.oppositeIpPort = udpOppositeIpPort this.stashFn = () => { } this.udp = socket.constructUDPSocketInstance(); } getStatus() { return this.isWorking } rebindUdp(localIp: string, localIpPort: string, oppositeIp: string, oppositeIpPort: string) { this.localIp = localIp this.oppositeIp = oppositeIp this.localIpPort = localIpPort this.oppositeIpPort = oppositeIpPort let promise = this.udp.bind({ // address: '192.168.7.170', port: 20122, family: 1 address: this.localIp, port: parseInt(this.localIpPort), family: 1 }); promise.then(() => { // globalThis.closeHeartSocket=false this.isWorking = true console.log(`${TAG} udp bind success`); }).catch(err => { //globalThis.closeHeartSocket=true this.isWorking = false console.log(`${TAG} udp bind failed:${JSON.stringify(err)}`); }); } bindUdp() { let promise = this.udp.bind({ address: this.localIp, port: parseInt(this.localIpPort), family: 1 }); promise.then(() => { this.isWorking = true console.log(`${TAG} udp bind success`); }).catch(err => { this.isWorking = false console.log(`${TAG} udp bind failed:${JSON.stringify(err)}`); }); } //异或运算 setMessageExclusive(tmpList) { let result = tmpList[0]; for (let i = 1; i < tmpList.length; i++) { result = result ^ tmpList[i] } return [result]; } Array2Byte(array) { var buf = new ArrayBuffer(array.length); var view = new Uint8Array(buf); for (var i = 0; i != array.length; ++i) { view[i] = array[i] & 0xFF; } return view; } //length消息体bufferlength id消息类型id bodyStr消息体string // setMsyBody(id,bodyByte){ // {id: 31,list:[0,1,'0000000000000'],carNo:489,placeId:62} setWholeMsg(params) { let head = this.setMsgHead(params); let headJudge = this.setMessageExclusive(head); let body = this.setMsgBody(params); let bodyJudge = this.setMessageExclusive(body); let end = [13, 10]; const arr = [...head, ...headJudge, ...body, ...bodyJudge, ...end] console.log('BitArray', arr) return this.Array2Byte(arr).buffer } setMsgHead({id, list, placeId=62, carNo=489}) { console.log('globalThis.lshNo', globalThis.lshNo) let a = string2Bytes(`${id}${fillZero(placeId, 3)}`, 2 * 8); console.log('aaa', a) let b = string2Bytes(`${fillZero(carNo, 4)}${globalThis.lshNo}`, 4 * 8); console.log('bbb', b) let c = string2Bytes(list.length, 2 * 8); return [...a, ...b, ...c]; } setMsgBody({id,list}) { let tmpList = [] tmpList = list return tmpList; } sendHeadMsg(msgData) { console.log('sendHeadMsg enter') this.sendMsg(msgData, null) console.log('sendHeadMsg exit') } sendMsg(msg, sendCallback?) { if (!this.isWorking && sendCallback) { sendCallback() } this.udp.getState((err, data) => { if (err) { this.isWorking = false return; } else { let promise = this.udp.send({ data: msg, address: { address: this.oppositeIp, port: parseInt(this.oppositeIpPort), } }); promise.then(() => { if (sendCallback) { sendCallback() } console.log(`${TAG}udpCLient udp send success:oppositeIp${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort,${this.localIpPort}`); }).catch(err => { console.log(`${TAG}udpCLient udp send fail:oppositeIp${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort,${this.localIpPort}`); }); } console.log('getState success:' + JSON.stringify(data)); }) } sendMsgExt(param, context?) { console.log('sendMsgExt enter'); if (context) { this.context = context } this.sendId = param.id const msgData = this.setWholeMsg(param) this.sendMsg(msgData, param.sendCallback) } onError_Callback(callback?) { this.udp.on('error', async err => { this.isWorking = false; console.log('UdpClientByCenter onError err:' + JSON.stringify(err)); callback && callback() }); } onError_resend(callback?) { this.udp.on('error', async err => { this.isWorking = false; console.log(TAG, 'udpError', JSON.stringify(err)) await this.bindUdp() await this.sendMsg('111', null) await this.onMessage_1(callback) callback && callback() }); } setMsgCallBack(callback) { this.stashFn = callback ? callback : () => { } } //中心udp回执 onMessage_2(callback, type?) { this.udp.on('message', (value, remoteInfo) => { console.log('UdpClientByCenter onMessage msg:' + JSON.stringify(value)); let arr = [] let dataView = new DataView(value.message) for (let i = 0; i < dataView?.byteLength; ++i) { arr[i] = dataView?.getUint8(i) } let idNum = '0x' + fillZero(arr[1].toString(16), 2) + fillZero(arr[0].toString(16), 2); let id = Math.floor(+idNum / 1000) hilog.info(0x0000, 'bitbit', JSON.stringify(arr)); let lengthNum = '0x' + fillZero(arr[7].toString(16), 2) + fillZero(arr[6].toString(16), 2); let length = +lengthNum; let list = [] for (let i = this.headLenth; i <= this.headLenth + length - 1; i++) { list.push(arr[i]) } this.stashFn({ id, length, body: list, sendId: this.sendId }) callback({ id, length, body: list, sendId: this.sendId }) }); } closeUdp(callback?) { console.log('UdpClientByCenter enter closeUdp ip:' + this.localIp + ' port:' + this.localIpPort); this.udp.close(err => { if (err) { console.log('UdpClientByCenter closeUdp failed ip:' + this.localIp + ' port:' + this.localIpPort + ' err:' + JSON.stringify(err)); } else { this.isWorking = false if (callback != null) { callback() } console.log('UdpClientByCenter closeUdp succeed ip:' + this.localIp + ' port:' + this.localIpPort); } }) } //plc onMessage_1(callback?) { this.onMessage_1Callback = callback; this.udp&&this.udp.on('message', this.message_1Fn); } closeMessage_1(){ console.info('surenjun', '关闭udp message监听事件') this.udp.off('message',this.message_1Fn); console.info('surenjun', '关闭udp message监听事件 成功') } message_1Fn = (value)=>{ console.log(TAG, 'udponmessage') let callback = this.onMessage_1Callback // 收到的是ArrayBuffer 需要进行转换解析 this.plcUdpError = false if (value) { let dataView = new DataView(value.message) let str = "" for (let i = 0; i < dataView?.byteLength; ++i) { let c = String.fromCharCode(dataView?.getUint8(i)) if (c !== "\n") { str += c } } console.log(`${TAG} udp on message array buffer:${str}`); let strachArr = str.split(',') if (strachArr[0] != '#DN_GD') { return } console.log(`${TAG} udp222 on message array buffer:${str}`); strachArr[28] = globalThis.chuankoMsg || '0' // this.stashFn(str) const newArr = JSON.parse(JSON.stringify(strachArr)) // this.stashFn=()=>{} callback && callback(newArr.toString()) this.currentValue = newArr.toString(); } else { callback && callback('') } console.log('messageTimeEnd') this.testIfUdpConnetced(callback) } //获取当前UDP信号 getCurrentMessage = () => { return this.currentValue } testIfUdpConnetced(callback) { const arrRed = [0x55, 0xaa, 0x01, 0x01, 0x02, 0x00, 0x03, 0x00]; const arrBlue = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00]; const arrGreen = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x00, 0x03, 0x01]; const arrBlueBuffer = Array2Byte(arrBlue).buffer const arrRedBuffer = Array2Byte(arrRed).buffer const arrGreenBugger = Array2Byte(arrGreen).buffer let num = 0 //监听udp是否断开 clearInterval(globalThis.messageTimer) globalThis.messageTimer = setInterval(() => { const lightLineUdp = globalThis.lightLineUdp const isJudge = globalThis.isJudge setTimeout(async () => { //程序断开 lightLineUdp?.send(this.plcUdpError ? arrRedBuffer : (isJudge ? arrGreenBugger : arrBlueBuffer)); if (this.plcUdpError) { num++ console.log(TAG, 'plc udp信号丢失') if (num == 3) { await this.bindUdp() await this.sendMsg('111', null) await this.onMessage_1(callback) num = 0 } prompt.showToast({ message: 'plc udp信号丢失', duration: 2000 }); } this.plcUdpError = true; }, 2000) }, 3000) } // initHeartSendMsg(param,context){ // console.log('1111param',JSON.stringify(param)) // this.initParam=param // this.context=context // } } interface StashFunction { (params: { id: number; length: number; body: any[]; sendId: string }): void; }