修改队列和启动重连

This commit is contained in:
2026-06-01 15:51:12 +08:00
parent 562881cc6c
commit 92165c914a
3 changed files with 73 additions and 39 deletions
+3
View File
@@ -8,3 +8,6 @@ data/
.vscode/launch.json
unpackage/
pnpm-lock.yaml
.vscode/
.hbuilderx/
.codegraph/
+28 -37
View File
@@ -129,9 +129,6 @@ export default {
this.addLog('手动关门错误', error)
}
})
// 启动左门循环定时器
// this.startLeftDoorCycle()
},
onShow() {
@@ -189,10 +186,9 @@ export default {
try {
this.startRS485()
this.startRS232()
// 启动心跳检测
// this.startHeartbeat()
} catch (e) {
// console.log(e)
uni.showToast({
title: '初始化串口失败',
icon: 'error'
@@ -376,13 +372,23 @@ export default {
clearInterval(this.timer)
this.readData()
// 启动心跳检测
this.startHeartbeat()
// 串口打开成功后,重置重连计数器和时间戳
// this.reconnectCount = 0
// this.last485DataTime = Date.now()
this.reconnectCount = 0
this.last485DataTime = Date.now()
// 记录通信恢复日志
// this.addLog('485通信', '通信已恢复(重连成功)')
}
} else {
// 确保心跳是关闭的
this.stopHeartbeatIfNeeded()
uni.showToast({
title: '485打开失败',
icon: 'error'
})
}
},
async startRS232() {
// 获取本地串口存储端口
@@ -413,6 +419,8 @@ export default {
}
},
stopRS485() {
// 停止心跳检测
this.stopHeartbeatIfNeeded()
this.addLog('485通信', '串口关闭')
this.RS485.stopReadPortData()
this.RS485.close()
@@ -430,7 +438,6 @@ export default {
clearInterval(this.heartbeatTimer)
this.heartbeatTimer = null
}
// 记录日志
this.addLog('485通信', '心跳检测已启动')
@@ -439,6 +446,17 @@ export default {
this.check485Heartbeat()
}, 10000)
},
// 停止心跳检测(安全方法,如果没运行也不会报错)
stopHeartbeatIfNeeded() {
if (!this.heartbeatTimer) {
// 心跳未运行
return
}
clearInterval(this.heartbeatTimer)
this.heartbeatTimer = null
this.addLog('485通信', '心跳检测已停止')
},
// 检测485数据心跳,如果超时则触发重连
check485Heartbeat() {
@@ -507,12 +525,6 @@ export default {
// 5. 重新启动RS485通信
this.startRS485()
// 6. 延迟后重新启动心跳检测(等待RS485初始化完成)
await delay(3000)
this.startHeartbeat()
this.addLog('485通信', '监听已重置(第' + this.reconnectCount + '次)')
} catch (error) {
this.addLog('485通信错误', error.message || '重置失败')
@@ -966,27 +978,6 @@ export default {
}
}
},
/**
* 左门循环开关(调试用,独立定时器)
* 每5秒切换一次左门状态
*/
startLeftDoorCycle() {
clearInterval(this.leftDoorCycleTimer)
let isOpen = false
this.leftDoorCycleTimer = setInterval(async () => {
try {
if (isOpen) {
cmd.LeftDoor(false)
} else {
cmd.LeftDoor(true)
}
isOpen = !isOpen
} catch (error) {
this.addLog('左门循环错误', error.message || error)
}
}, 5000)
},
}
}
+42 -2
View File
@@ -25,13 +25,50 @@ const PRIORITY = {
const rs485Queue = []
let isRS485Sending = false
const RS485_SEND_DELAY = 200 // 每条指令间隔200ms,确保总线空闲
const MAX_QUEUE_SIZE = 3 // 队列最大长度
/**
* 将任务按优先级插入队列
* 高优先级(0)插入到队列前面低优先级任务之前
* 低优先级(1)追加到队列末尾
* 规则:
* 1. 队列最大长度为3
* 2. 重复指令(相同cmd)不入队,直接丢弃
* 3. 队列满时,高优先级任务挤掉低优先级任务,否则踢掉最老的(队首)
*/
const enqueueTask = (task) => {
// 规则1: 去重 - 已存在相同cmd的任务则丢弃
const isDuplicate = rs485Queue.some(t => t.cmd === task.cmd)
if (isDuplicate) {
console.warn('[RS485队列] 丢弃重复任务:', task.cmd)
return false
}
// 规则2: 队列满了,先腾位置
if (rs485Queue.length >= MAX_QUEUE_SIZE) {
if (task.priority === PRIORITY.HIGH) {
// 高优先级:优先挤掉队列中最后一个低优先级任务
let lastLowIndex = -1
for (let i = rs485Queue.length - 1; i >= 0; i--) {
if (rs485Queue[i].priority === PRIORITY.LOW) {
lastLowIndex = i
break
}
}
if (lastLowIndex !== -1) {
console.warn('[RS485队列] 高优挤掉低优:', rs485Queue[lastLowIndex].cmd)
rs485Queue.splice(lastLowIndex, 1)
} else {
// 没有低优先级可挤,踢掉队首最老的
console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd)
rs485Queue.shift()
}
} else {
// 低优先级:直接踢掉队首最老的
console.warn('[RS485队列] 满,踢掉队首:', rs485Queue[0].cmd)
rs485Queue.shift()
}
}
// 规则3: 按优先级插入
if (task.priority === PRIORITY.HIGH) {
let insertIndex = rs485Queue.findIndex(t => t.priority === PRIORITY.LOW)
if (insertIndex === -1) {
@@ -42,6 +79,9 @@ const enqueueTask = (task) => {
} else {
rs485Queue.push(task)
}
console.log(`[RS485队列] 入队成功, 长度:${rs485Queue.length}, cmd:${task.cmd}`)
return true
}
const processRS485Queue = async () => {