468 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			468 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /*
 | ||
|  * 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'
 | ||
| import promptAction from '@ohos.promptAction';
 | ||
| import { getUDP } from './GlobalUdp';
 | ||
| import { dateFormat } from '../utils/tools'
 | ||
| import { getSyncData } from '../service/initable';
 | ||
| 
 | ||
| 
 | ||
| export default class UdpClientByCenter {
 | ||
|   private localIp: string = ''
 | ||
|   private localIpPort: string = ''
 | ||
|   private oppositeIp: string = ''
 | ||
|   private oppositeIpPort: string = ''
 | ||
|   private udpMsg: any = ''
 | ||
|   private chafenFlag: number = 0
 | ||
|   private num: number = 0
 | ||
|   private fileUtil: FileUtil
 | ||
|   private udp: UDPSocket = null
 | ||
|   private sendId: any = 0
 | ||
|   private lsh: string = null
 | ||
|   private context
 | ||
|   private folderPath
 | ||
|   private stashFn: StashFunction
 | ||
|   private errorStep: number=0
 | ||
|   private interval
 | ||
|   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();
 | ||
|     this.initPath()
 | ||
|   }
 | ||
| 
 | ||
|   getStatus() {
 | ||
|     return this.isWorking
 | ||
|   }
 | ||
| 
 | ||
|   rebindUdp(localIp: string, localIpPort: string, oppositeIp: string, oppositeIpPort: string)
 | ||
|   {
 | ||
|     console.log(`${TAG}getUDPudpCLient rebindUdp enter localIp:${localIp},localIpPort:${localIpPort},oppositeIp:${oppositeIp},oppositeIpPort:${oppositeIpPort}`);
 | ||
|     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} getUDPudp rebind success`);
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC:`${TAG} getUDPudp rebind success`,
 | ||
|       // })
 | ||
|     }).catch(err => {
 | ||
|       //globalThis.closeHeartSocket=true
 | ||
|       this.isWorking = false
 | ||
|      // this.writeLog({
 | ||
|      //    time:dateFormat(new Date()),
 | ||
|      //    PLC:`${TAG} getUDPudp rebind failed:${JSON.stringify(err)}`,
 | ||
|      //  })
 | ||
|       console.log(`${TAG} getUDPudp rebind failed:${JSON.stringify(err)}`);
 | ||
|     });
 | ||
|   }
 | ||
| 
 | ||
|   bindUdp() {
 | ||
|     let promise = this.udp.bind({
 | ||
|       address: this.localIp, port: parseInt(this.localIpPort), family: 1
 | ||
|     });
 | ||
|     promise.then(() => {
 | ||
|       this.isWorking = true
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC:`${TAG} getUDPudp bind success`,
 | ||
|       // })
 | ||
|     }).catch(err => {
 | ||
|       this.isWorking = false
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC:`${TAG} getUDPudp bind error${JSON.stringify(err)},localIp:${this.localIpPort},port:${this.localIpPort}`,
 | ||
|       // })
 | ||
|     });
 | ||
|   }
 | ||
| 
 | ||
|   //异或运算
 | ||
|   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('getUDPsendHeadMsg enter')
 | ||
|     this.sendMsg(msgData, null)
 | ||
|     console.log('getUDPsendHeadMsg exit')
 | ||
|   }
 | ||
| 
 | ||
|   sendMsg(msg, sendCallback?)
 | ||
|   {
 | ||
|     if (!this.isWorking ) {
 | ||
|       console.log(`${TAG}getUDPudpCLient sendMsg  is closed return `);
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC:`${TAG}getUDPudpCLient  sendMsg  is closed return oppositeIp:${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort:${this.localIpPort}`,
 | ||
|       // })
 | ||
|       if(sendCallback) {
 | ||
|         sendCallback()
 | ||
|       }
 | ||
|       return;
 | ||
|     }
 | ||
|     let promise = this.udp.send({
 | ||
|       data: msg,
 | ||
|       address: {
 | ||
|         address: this.oppositeIp,
 | ||
|         port: parseInt(this.oppositeIpPort),
 | ||
|       }
 | ||
|     });
 | ||
|     promise.then(() => {
 | ||
|       if (sendCallback) {
 | ||
|         sendCallback()
 | ||
|       }
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC:`${TAG}getUDPudpCLient udp send success: oppositeIp:${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort:${this.localIpPort}`,
 | ||
|       // })
 | ||
|     }).catch(err => {
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC:`${TAG}getUDPudpCLient udp send fail:oppositeIp${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort,${this.localIpPort}${JSON.stringify(err)}`,
 | ||
|       // })
 | ||
|       promptAction.showToast({
 | ||
|         message:`${TAG}getUDPudpCLient udp send fail:oppositeIp${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort,${this.localIpPort}`,
 | ||
|         duration:4000
 | ||
|       })
 | ||
|     });
 | ||
|   }
 | ||
| 
 | ||
|   sendMsgExt(param, context?) {
 | ||
|     console.log('sendMsgExt enterbitbit',JSON.stringify(param));
 | ||
|     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;
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC:'getUDPUdpClientByCenter  onError err:' + JSON.stringify(err)+this.oppositeIpPort,
 | ||
|       // })
 | ||
|       callback && callback()
 | ||
|     });
 | ||
|   }
 | ||
| 
 | ||
|   onError_resend(callback?) {
 | ||
|     this.udp.on('error', async err => {
 | ||
|       this.isWorking = false;
 | ||
| 
 | ||
|       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)
 | ||
| 
 | ||
|       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
 | ||
|       })
 | ||
|       hilog.info(0x0000, 'bitbitarrrbitbitarrr', JSON.stringify({
 | ||
|         id, length, body: list, sendId: this.sendId
 | ||
|       }));
 | ||
| 
 | ||
| 
 | ||
|       // this.interval=setInterval(()=>{
 | ||
|       //
 | ||
|       // },3000)
 | ||
| 
 | ||
|     });
 | ||
|   }
 | ||
| 
 | ||
|   closeUdp(callback?) {
 | ||
|     console.log('getUDPUdpClientByCenter  enter closeUdp ip:' + this.localIp + ' port:' + this.localIpPort);
 | ||
|     this.udp.close(err => {
 | ||
|       if (err) {
 | ||
|         // this.writeLog({
 | ||
|         //   time:dateFormat(new Date()),
 | ||
|         //   PLC:'getUDPUdpClientByCenter  closeUdp err:' + JSON.stringify(err)+this.oppositeIpPort,
 | ||
|         // })
 | ||
|       } else {
 | ||
|         this.isWorking = false
 | ||
|         if (callback != null) {
 | ||
|           callback()
 | ||
|         }
 | ||
|         // this.writeLog({
 | ||
|         //   time:dateFormat(new Date()),
 | ||
|         //   PLC:'getUDPUdpClientByCenter  closeUdp succeed:' + JSON.stringify(err)+this.oppositeIpPort,
 | ||
|         // })
 | ||
|       }
 | ||
|     })
 | ||
|   }
 | ||
| 
 | ||
|   //plc
 | ||
|   onMessage_1(callback?) {
 | ||
|     this.onMessage_1Callback = callback;
 | ||
|     this.udp&&this.udp.on('message', this.message_1Fn);
 | ||
|   }
 | ||
| 
 | ||
|   closeMessage_1(){
 | ||
|     console.info('surenjun', 'getUDP关闭udp message监听事件')
 | ||
|     this.udp.off('message',this.message_1Fn);
 | ||
|     console.info('surenjun', 'getUDP关闭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
 | ||
|       }
 | ||
| 
 | ||
|       strachArr[28] = globalThis.chuankoMsg || strachArr[28]
 | ||
|       console.log(`${TAG} udp222 on message array buffer:${str}`);
 | ||
| 
 | ||
|       // this.stashFn(str)
 | ||
|       const newArr = JSON.parse(JSON.stringify(strachArr))
 | ||
|       // this.writeLog({
 | ||
|       //   time:dateFormat(new Date()),
 | ||
|       //   PLC: JSON.stringify(newArr.toString()),
 | ||
|       // })
 | ||
|       if(strachArr[83]!='4'){
 | ||
|         console.log('差分状态异常',strachArr[83],strachArr[92])
 | ||
|         this.writeLog({
 | ||
|           time:dateFormat(new Date()),
 | ||
|           PLC: `${TAG}差分状态异常,${strachArr[83]},${strachArr[92]}`,
 | ||
|         })
 | ||
|       }else{
 | ||
|         globalThis.dialogOpen=false
 | ||
|         this.chafenFlag=0
 | ||
|       }
 | ||
|       callback && callback(newArr.toString())
 | ||
|       this.currentValue = newArr.toString();
 | ||
|     } else {
 | ||
|       callback && callback('')
 | ||
|     }
 | ||
| 
 | ||
|     console.log('messageTimeEnd')
 | ||
|     this.testIfUdpConnetced(callback)
 | ||
|   }
 | ||
|   async  writeLog(param){
 | ||
|     // const fileUtil = new FileUtil(globalThis.context)
 | ||
|     // fileUtil.editFile(`${this.folderPath}/plcLog.txt`, JSON.stringify(param)+`\n`)
 | ||
|   }
 | ||
|   async initPath(){
 | ||
|     // const fileUtil = new FileUtil(globalThis.context)
 | ||
|     // const date=dateFormat(new Date).split(' ')[0]
 | ||
|     // this.folderPath = await fileUtil.initFolder(`/PLC/${date}`);
 | ||
|   }
 | ||
|   //获取当前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
 | ||
|     globalThis.dialogOpen=false
 | ||
| 
 | ||
|     //监听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++
 | ||
|           this.writeLog({
 | ||
|             time:dateFormat(new Date()),
 | ||
|             PLC: 'plc udp信号丢失',
 | ||
|           })
 | ||
|           console.log(TAG, 'plc udp信号丢失')
 | ||
|           if (num == 3) {
 | ||
|             getUDP(globalThis.context,true)
 | ||
|             globalThis.title='plc udp信号丢失'
 | ||
|             globalThis.type='3'
 | ||
|             if(!globalThis.dialogOpen){
 | ||
|               // AppStorage.SetOrCreate('errorCode', 1);
 | ||
|               // if(this.errorStep!=1){
 | ||
|               //   console.log('sys.v_valuesys.v_valuesys.v_value11221')
 | ||
|               //
 | ||
|               //   this.errorStep=1
 | ||
|               //   this.avPlayer.playAudio(['voice/差分状态异常.wav'])
 | ||
|               //   getSyncData('MA_SYSSET').then(syssetParams => {
 | ||
|               //     console.log('sys.v_valuesys.v_valuesys.v_value11221',JSON.stringify(syssetParams))
 | ||
|               //     // @ts-ignore
 | ||
|               //     syssetParams.forEach(sys => {
 | ||
|               //       // 差分长时间是SINGLE状态报考车故障,停止考试(0-否 1-是)
 | ||
|               //       if (sys.v_no === '424'&&sys.v_value==1){
 | ||
|               //         //plc差分丢失
 | ||
|               //         AppStorage.SetOrCreate('errorCode', 0);
 | ||
|               //         AppStorage.SetOrCreate('errorCodeFlage', true);
 | ||
|               //
 | ||
|               //       }
 | ||
|               //     })
 | ||
|               //     // const errorParam = syssetParams.filter(sys => sys.v_no === '424') //
 | ||
|               //     // that.studentRefreshStatue = studentRefreshParam?.[0]?.v_value || '0'
 | ||
|               //
 | ||
|               //
 | ||
|               //   });
 | ||
|               // }
 | ||
|             }
 | ||
|             num = 0
 | ||
|           }
 | ||
| 
 | ||
|           prompt.showToast({
 | ||
|             message: 'plc udp信号丢失',
 | ||
|             duration: 2000
 | ||
|           });
 | ||
|         }
 | ||
| 
 | ||
|         this.plcUdpError = true;
 | ||
|       }, 2000)
 | ||
|     }, 2000)
 | ||
|   }
 | ||
| 
 | ||
|   // 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;
 | ||
| } |