You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理并发POST请求?树莓派GPIO继电器防闪烁重叠需求问询

解决POST请求并发导致灯光闪烁重叠的问题

这个问题的核心是要保证灯光闪烁操作的互斥性——同一时间只能有一个闪烁任务在执行,所以我们可以通过一个状态标记来实现“忙则忽略”的逻辑,具体方案如下:

核心思路

添加一个全局状态变量来标记当前是否正在执行闪烁操作:

  • 当收到POST请求时,先检查这个状态,如果正在闪烁,直接返回响应忽略请求
  • 如果空闲,则标记为“忙碌”,执行闪烁逻辑
  • 闪烁完成后,重置状态为“空闲”,允许后续请求处理

修改后的代码示例

假设你使用onoff库控制GPIO(如果用其他库,调整GPIO操作部分即可):

var app = require('express')();
var http = require('http').Server(app);
var bodyParser = require("body-parser"); // 补全解析器依赖
var Gpio = require('onoff').Gpio;

// 初始化继电器(根据你的实际GPIO引脚调整)
const relay = new Gpio(17, 'out');
// 闪烁总时长(X秒,这里示例为5秒)
const BLINK_DURATION = 5000;
// 状态标记:是否正在闪烁
let isBlinking = false;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json()); // 支持JSON格式的POST请求

app.post('/truck-alert', (req, res) => {
    // 检查当前是否正在闪烁,是则直接返回
    if (isBlinking) {
        return res.status(409).send('Light is currently active, request skipped');
    }

    // 标记为忙碌状态
    isBlinking = true;
    let blinkTimer;

    try {
        // 启动闪烁:每隔500ms切换继电器状态
        blinkTimer = setInterval(() => {
            // 翻转继电器状态(0变1,1变0)
            relay.writeSync(relay.readSync() ^ 1);
        }, 500);

        // 到设定时长后停止闪烁,重置状态
        setTimeout(() => {
            clearInterval(blinkTimer);
            // 确保继电器最终处于关闭状态(根据你的需求调整)
            relay.writeSync(0);
            isBlinking = false;
            console.log('Blink cycle completed, ready for next alert');
        }, BLINK_DURATION);

        // 返回成功响应
        res.status(200).send('Alert triggered, light is blinking');
    } catch (error) {
        // 出错时清理资源,重置状态,避免锁死
        console.error('Error handling alert:', error);
        if (blinkTimer) clearInterval(blinkTimer);
        relay.writeSync(0);
        isBlinking = false;
        res.status(500).send('Failed to trigger alert');
    }
});

http.listen(3000, () => {
    console.log('Server running on port 3000');
});

// 程序退出时释放GPIO资源,避免树莓派引脚异常
process.on('SIGINT', () => {
    relay.unexport();
    process.exit();
});

关键细节说明

  1. 状态锁isBlinking:这个变量是整个逻辑的核心,它确保了同一时间只有一个闪烁任务能被执行,完全避免了重叠问题。
  2. 资源清理:
    • 每次闪烁结束后,必须清理定时器并重置继电器状态,避免设备处于异常状态
    • 程序退出时要释放GPIO资源,这是树莓派GPIO编程的最佳实践
  3. 错误处理:添加try-catch块,确保即使闪烁过程中出现错误,也能重置isBlinking状态,不会导致后续请求一直被忽略。

如果你的GPIO控制库不是onoff,只需要替换继电器操作的相关代码即可,核心的状态控制逻辑是通用的。

内容的提问来源于stack exchange,提问作者Adolfo Alonso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:50:28