fix(led): VFD 管道用 O_NONBLOCK 防止事件循环阻塞

FIFO 写入改为 O_WRONLY | O_NONBLOCK:
- 无读端(vfdservice 关闭读端后)openSync 立即抛 ENXIO 而非永久阻塞
- showPin blink timer 每 500-1000ms 自动重试,vfdservice 恢复读后
  即可成功显示 PIN,彻底解决"长时间激活后解绑 PIN 不闪"问题

同时移除 66b94d8 加的 showTime keepalive:
- keepalive 用的也是阻塞 openSync,vfdservice 关闭读端时反而会
  在 setTimeout 回调里阻塞整个事件循环,比不加更危险

Made-with: Cursor
This commit is contained in:
stswangzhiping
2026-04-03 19:01:14 +08:00
parent 66b94d828f
commit fb8a408f93

View File

@@ -46,6 +46,9 @@ function vfdTitleNormalize(raw) {
.padEnd(4, ' ');
}
// O_WRONLY | O_NONBLOCKFIFO 无读端时立即抛 ENXIO 而非永久阻塞事件循环
const VFD_OPEN_FLAGS = fs.constants.O_WRONLY | fs.constants.O_NONBLOCK;
function writeVfdPipeTitle(text4) {
if (!vfdPipePresent()) return;
const seg = vfdTitleNormalize(text4);
@@ -58,7 +61,7 @@ function writeVfdPipeTitle(text4) {
return;
}
try {
const fd = fs.openSync(VFD_PIPE, 'w');
const fd = fs.openSync(VFD_PIPE, VFD_OPEN_FLAGS);
fs.writeSync(fd, data);
fs.closeSync(fd);
} catch (e) {
@@ -71,7 +74,7 @@ function writeVfdPipeClock() {
const data = Buffer.alloc(VFD_BUF_SIZE);
data.writeUInt16LE(VFD_MODE_CLOCK, 0);
try {
const fd = fs.openSync(VFD_PIPE, 'w');
const fd = fs.openSync(VFD_PIPE, VFD_OPEN_FLAGS);
fs.writeSync(fd, data);
fs.closeSync(fd);
} catch (e) {
@@ -256,13 +259,6 @@ class Display {
this._stopBlink();
writeVfdPipeClock();
log.info('display', '显示屏 → 时间');
// 每 30s 刷新一次,保持 vfdservice 持续从管道读取,
// 防止长时间无写入后管道"冷却",导致后续 showPin 写入阻塞
const refresh = () => {
writeVfdPipeClock();
this._blinkTimer = setTimeout(refresh, 30_000);
};
this._blinkTimer = setTimeout(refresh, 30_000);
}
showPin(pin) {