Compare commits

...

3 Commits

Author SHA1 Message Date
cfe1852b03 udp修改 2025-03-18 19:39:11 +08:00
b6ebb37d11 Merge branch 'api10' of http://47.122.70.237:3000/harmony_car/subject-two into api10
# Conflicts:
#	entry/src/main/ets/utils/UdpUtils.ets
2025-03-18 19:07:47 +08:00
839b6f6f39 优化udp 2025-02-19 10:11:05 +08:00
5 changed files with 273 additions and 90 deletions

View File

@ -43,15 +43,16 @@ export default class UdpClientByCenter {
private lsh: string = null
private folderPath
private stashFn: StashFunction
private errorStep: number=0
private messageTimer:number=-1
private errorStep: number = 0
private messageTimer: number = -1
private headLenth: number = 9
//消息头长度
private isWorking: Boolean = false
private plcUdpError = false;
private initParam
private onMessage_1Callback:Function = ()=>{}
public currentValue:string = ''
private onMessage_1Callback: Function = () => {
}
public currentValue: string = ''
constructor(udplocalIp: string, udplocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) {
this.localIp = udplocalIp
@ -64,12 +65,7 @@ export default class UdpClientByCenter {
this.initPath()
}
getStatus() {
return this.isWorking
}
rebindUdp(localIp: string, localIpPort: string, oppositeIp: string, oppositeIpPort: string)
{
rebindUdp(localIp: string, localIpPort: string, oppositeIp: string, oppositeIpPort: string) {
this.localIp = localIp
this.oppositeIp = oppositeIp
this.localIpPort = localIpPort
@ -88,10 +84,10 @@ export default class UdpClientByCenter {
// })
}).catch(err => {
this.isWorking = false
// this.writeLog({
// time:dateFormat(new Date()),
// PLC:`${TAG} getUDPudp rebind failed:${JSON.stringify(err)}`,
// })
// this.writeLog({
// time:dateFormat(new Date()),
// PLC:`${TAG} getUDPudp rebind failed:${JSON.stringify(err)}`,
// })
console.log(`${TAG} getUDPudp rebind failed:${JSON.stringify(err)}`);
});
}
@ -148,14 +144,14 @@ export default class UdpClientByCenter {
}
setMsgHead({id, list, placeId=62, carNo=489}) {
setMsgHead({ id, list, placeId=62, carNo=489 }) {
let a = string2Bytes(`${id}${fillZero(placeId, 3)}`, 2 * 8);
let b = string2Bytes(`${fillZero(carNo, 4)}${AppStorage.get('lshNo')}`, 4 * 8);
let c = string2Bytes(list.length, 2 * 8);
return [...a, ...b, ...c];
}
setMsgBody({id,list}) {
setMsgBody({ id, list }) {
let tmpList = []
tmpList = list
@ -169,15 +165,14 @@ export default class UdpClientByCenter {
console.log('getUDPsendHeadMsg exit')
}
sendMsg(msg, sendCallback?)
{
if (!this.isWorking ) {
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) {
if (sendCallback) {
sendCallback()
}
return;
@ -203,8 +198,8 @@ export default class UdpClientByCenter {
// 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
message: `${TAG}getUDPudpCLient udp send fail:oppositeIp${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort,${this.localIpPort}`,
duration: 4000
})
});
}
@ -241,6 +236,7 @@ export default class UdpClientByCenter {
this.stashFn = callback ? callback : () => {
}
}
//中心udp回执
onMessage_2(callback, type?) {
this.udp.on('message', (value, remoteInfo) => {
@ -259,14 +255,19 @@ export default class UdpClientByCenter {
list.push(arr[i])
}
this.stashFn({
id, length, body: list, sendId: this.sendId
id,
length,
body: list,
sendId: this.sendId
})
callback({
id, length, body: list, sendId: this.sendId
id,
length,
body: list,
sendId: this.sendId
})
// this.interval=setInterval(()=>{
//
// },3000)
@ -295,19 +296,7 @@ export default class UdpClientByCenter {
})
}
//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)=>{
message_1Fn = (value) => {
let callback = this.onMessage_1Callback
// 收到的是ArrayBuffer 需要进行转换解析
this.plcUdpError = false
@ -334,14 +323,14 @@ export default class UdpClientByCenter {
// time:dateFormat(new Date()),
// PLC: JSON.stringify(newArr.toString()),
// })
if(strachArr[83]!='4'){
console.log('差分状态异常',strachArr[83],strachArr[92])
if (strachArr[83] != '4') {
console.log('差分状态异常', strachArr[83], strachArr[92])
this.writeLog({
time:dateFormat(new Date()),
time: dateFormat(new Date()),
PLC: `${TAG}差分状态异常,${strachArr[83]},${strachArr[92]}`,
})
}else{
this.chafenFlag=0
} else {
this.chafenFlag = 0
}
callback && callback(newArr.toString())
this.currentValue = newArr.toString();
@ -351,15 +340,18 @@ export default class UdpClientByCenter {
this.testIfUdpConnetced(callback)
}
async writeLog(param){
async writeLog(param) {
// const fileUtil = new FileUtil(globalThis.context)
// fileUtil.editFile(`${this.folderPath}/plcLog.txt`, JSON.stringify(param)+`\n`)
}
async initPath(){
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
@ -385,14 +377,14 @@ export default class UdpClientByCenter {
if (this.plcUdpError) {
num++
this.writeLog({
time:dateFormat(new Date()),
time: dateFormat(new Date()),
PLC: 'plc udp信号丢失',
})
console.log(TAG, 'plc udp信号丢失')
if (num == 3) {
getUDP(AppStorage.get('context'),true)
AppStorage.setOrCreate('title','plc udp信号丢失')
AppStorage.setOrCreate('type',3)
getUDP(AppStorage.get('context'), true)
AppStorage.setOrCreate('title', 'plc udp信号丢失')
AppStorage.setOrCreate('type', 3)
num = 0
}

View File

@ -10,6 +10,7 @@ import { GlobalConfig } from '../config/global'
import { tcpUtil } from '../common/utils/TcpRequest';
import DB from '../common/database/DbSql';
import { initTable } from '../common/service/initable';
import { centerUDPClient, lightUDPClient, objUDPClient } from '../utils/UdpUtils';
export default class EntryAbility extends UIAbility {
async onCreate(want, launchParam) {
@ -34,32 +35,36 @@ export default class EntryAbility extends UIAbility {
}
async onWindowStageCreate(windowStage: window.WindowStage) {
// 初始化示例,只需要调用一次
await objUDPClient.init(this.context)
await lightUDPClient.init(this.context)
await centerUDPClient.init(this.context)
// this.context
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
await tcpUtil.init()
AppStorage.setOrCreate('carInfo',{})
AppStorage.setOrCreate('examinerInfo',{})
AppStorage.setOrCreate('lsh','0000000000000')
AppStorage.setOrCreate('statue',1)//考试状态
AppStorage.setOrCreate('signNum',0)//心跳指令编号
AppStorage.setOrCreate('deviceNo',0)//设备号
AppStorage.setOrCreate('baseInfo',{
hasAuth:false,
version:GlobalConfig.version.jn.km3[0],
judgeVersion:GlobalConfig.version.jn.km3[1],
tcpSendNum:0,
videoVersion:'1.0',
AppStorage.SetOrCreate('carInfo', {})
AppStorage.SetOrCreate('examinerInfo', {})
AppStorage.SetOrCreate('lsh', '0000000000000')
AppStorage.SetOrCreate('statue', 1) //考试状态
AppStorage.SetOrCreate('signNum', 0) //心跳指令编号
AppStorage.SetOrCreate('deviceNo', 0) //设备号
AppStorage.SetOrCreate('baseInfo', {
hasAuth: false,
version: GlobalConfig.version.jn.km3[0],
judgeVersion: GlobalConfig.version.jn.km3[1],
tcpSendNum: 0,
videoVersion: '1.0',
ratio: 1700 / 960, //适配比例
pathDir: this.context.filesDir,
context: this.context,
isJudgeInitBool:false,
isJudgeInitBool: false,
})
const windowClass = await windowStage.getMainWindow();
AppStorage.setOrCreate('windowClass',windowClass)
AppStorage.SetOrCreate('windowClass', windowClass)
// await windowClass.setWindowLayoutFullScreen(true)
// await windowClass.setWindowSystemBarEnable([]) //全屏
await windowClass.setWindowSystemBarEnable(['navigation'])

View File

@ -1,43 +1,65 @@
import socket from '@ohos.net.socket'
import common from '@ohos.app.ability.common'
import FileUtils from './fileUtils'
import promptAction from '@ohos.promptAction'
type DealMethod = (value: ArrayBuffer) => string
interface IPConfig {
udplocalIp: string
udplocalIpPort: string
udpOppositeIp: string
udpOppositeIpPort: string
}
class UdpClient {
private localIp: string = ''
private localIpPort: string = ''
private oppositeIp: string = ''
private oppositeIpPort: string = ''
private messageEvents: Array<Function> = []
private udp: socket.UDPSocket = null
private disconnectEvents: Array<Function> = []
private messageEvents: Array<Function> = []
private errorEvents: Array<Function> = []
private dealMethod: DealMethod
init(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) {
protected create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) {
this.localIp = udpLocalIp
this.oppositeIp = udpOppositeIp
this.localIpPort = udpLocalIpPort
this.oppositeIpPort = udpOppositeIpPort
this.udp = socket.constructUDPSocketInstance();
this.bindEvent()
this.bindUdp()
}
private bindEvent() {
this.udp?.on("message", value => {
let result = this?.dealMethod(value.message)
this.messageEvents.forEach(cb => {
cb(result)
})
})
this.udp.on("error", (err) => {
this.errorEvents.forEach(cb => {
cb(err)
})
})
}
bindUdp(): Promise<void> {
return this.udp.bind({ address: this.localIp, port: parseInt(this.localIpPort), family: 1 }).then(() => {
try {
this.dealMessage()
return Promise.resolve()
} catch (e) {
return Promise.reject(e)
}
})
return this.udp.bind({ address: this.localIp, port: parseInt(this.localIpPort), family: 1 })
}
async reBind() {
await this.close()
this.udp = socket.constructUDPSocketInstance();
this.bindEvent()
await this.bindUdp()
}
close(): Promise<void> {
this.udp.off("message")
this.udp.off("error")
return this.udp?.close()
}
@ -49,8 +71,8 @@ class UdpClient {
this.messageEvents.push(callback)
}
onDisconnect(callback: Function) {
this.disconnectEvents.push(callback)
onError(callback: Function) {
this.errorEvents.push(callback)
}
sendMsg(data: string): Promise<void> {
@ -61,25 +83,69 @@ class UdpClient {
})
})
}
}
private dealMessage() {
this.udp?.on("message", value => {
let result = this?.dealMethod(value.message)
this.messageEvents.forEach(cb => {
cb(result)
class ObjUdpClient extends UdpClient {
async init(context: common.UIAbilityContext) {
try {
const fileUtil = new FileUtils(context)
const data = await fileUtil.readFile("" + '/config/ipConfig.txt');
if (data?.length > 0) {
const result: IPConfig = JSON.parse(data)
this.create(result.udplocalIp, result.udplocalIpPort, result.udpOppositeIp, result.udpOppositeIpPort)
}
} catch (e) {
promptAction.showToast({
message: "初始化obj udp失败"
})
})
}
}
}
export const objUDPClient = new UdpClient()
class CenterUDPClient extends UdpClient {
async init(context: common.UIAbilityContext) {
try {
const fileUtil = new FileUtils(context)
const data = await fileUtil.readFile("" + '/config/ipConfig.txt');
const carInfo: {
udpAddress: string
messagePort: string
} = AppStorage.Get('carInfo')
if (data?.length > 0) {
const result: IPConfig = JSON.parse(data)
this.create(result.udplocalIp, '8800', carInfo?.udpAddress, carInfo?.messagePort)
}
} catch (e) {
promptAction.showToast({
message: "初始化中心 udp失败"
})
}
}
}
// 中心心跳
export const centerUDPClient = new UdpClient()
class LightUDPClient extends UdpClient {
async init(context: common.UIAbilityContext) {
try {
const fileUtil = new FileUtils(context)
const data = await fileUtil.readFile("" + '/config/ipConfig.txt');
if (data?.length > 0) {
const result: IPConfig = JSON.parse(data)
this.create(result.udplocalIp, '55509', result.udpOppositeIp, result.udpOppositeIpPort)
}
} catch (e) {
promptAction.showToast({
message: "初始化灯光 udp失败"
})
}
}
}
// obj
export const objUDPClient = new ObjUdpClient()
// 中心
export const centerUDPClient = new CenterUDPClient()
// 中心GPS
// 顶灯
export const lightUDPClient = new UdpClient()
export const lightUDPClient = new LightUDPClient()
// 获取后置机信号
export const judgeUDPClient = new UdpClient()

View File

@ -0,0 +1,120 @@
import common from "@ohos.app.ability.common"
import Want from "@ohos.app.ability.Want"
import fileAccess from "@ohos.file.fileAccess"
import fs from '@ohos.file.fs'
import abilityAccessCtrl, { Permissions } from "@ohos.abilityAccessCtrl"
import promptAction from "@ohos.promptAction"
const LOG_TAG = '[file utils]'
export default class FileUtils {
private context: common.UIAbilityContext
private wantInfos: Want[]
private fileAccessHelper: fileAccess.FileAccessHelper
private absolutePath = '/mnt/hmdfs/100/account/device_view/local/files/duolun'
public destFile: string
public filePathFdObj: Record<string, fs.File> = {}
constructor(context: common.UIAbilityContext) {
this.context = context
this.requestPermission();
fs.mkdir(this.absolutePath)
}
private async requestPermission() {
let permissions: Array<Permissions> = [
'ohos.permission.READ_MEDIA',
'ohos.permission.WRITE_MEDIA'
];
this.wantInfos = await fileAccess.getFileAccessAbilityInfo();
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
atManager.requestPermissionsFromUser(this.context, permissions, async (code, result) => {
const permissionRequest = result.authResults[0]
if (permissionRequest == -1) {
promptAction.showToast({
message: "请先授权",
duration: 3000,
})
return
}
})
}
async initFolder(folderPath: string): Promise<string> {
const folderList = folderPath.split('/').filter(folderName => folderName !== '');
let path = this.absolutePath
folderList.forEach(folderName => {
path += `/${folderName}`;
try {
const isExit = fs.accessSync(path);
if (!isExit) {
fs.mkdirSync(path)
}
} catch (e) {
console.info('初始化文件夹失败', path)
promptAction.showToast({
message: `初始化文件夹失败` + folderPath + JSON.stringify(e),
duration: 4000,
})
}
})
return path
}
async addFile(filePath: string, content: string) {
try {
//文件存在先删除
if (fs.accessSync(filePath)) {
fs.unlinkSync(filePath);
}
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
//追加写入文件
fs.writeSync(file.fd, content)
fs.closeSync(file)
console.error(LOG_TAG, '写入文件成功')
return true
} catch (e) {
promptAction.showToast({
message: `addFile文件失败` + filePath + JSON.stringify(e),
duration: 4000,
})
console.error(LOG_TAG, '写入失败', JSON.stringify(e))
}
}
async editFile(filePath: string, content: string, fd?: number) {
const thisFile: fs.File = this.filePathFdObj[filePath];
try {
if (thisFile) {
fs.writeSync(thisFile.fd, content + '\n')
return fd;
} else {
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.APPEND | fs.OpenMode.CREATE);
fs.writeSync(file.fd, content + '\n')
this.filePathFdObj[filePath] = file
return file.fd
}
} catch (e) {
promptAction.showToast({
message: `editFile文件失败` + filePath + JSON.stringify(e),
duration: 4000,
})
console.error(LOG_TAG, JSON.stringify(e))
}
}
async readFile(filePath: string): Promise<string> {
try {
const str = await fs.readText(filePath);
return str
} catch (e) {
promptAction.showToast({
message: `读取文件失败` + filePath + JSON.stringify(e),
duration: 4000,
})
console.log('readFile文件失败' + filePath + JSON.stringify(e))
return ''
}
}
}

View File

@ -17,7 +17,7 @@
"abilities": [
{
"name": "EntryAbility",
"srcEntrance": "./ets/entryability/EntryAbility.ts",
"srcEntrance": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:logo_app",
"label": "$string:EntryAbility_label",