首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Node中创建长时间运行、可中断功能的策略?

在Node中创建长时间运行、可中断功能的策略?
EN

Stack Overflow用户
提问于 2013-07-22 20:53:29
回答 2查看 260关注 0票数 0

我希望在Node中创建一个服务器,它将运行在我的Raspberry Pi上,以处理更改的GPIO引脚。(我对Node很陌生,但很高兴能学到新东西)

这些引脚控制喷淋阀继电器使用OpenSprinkler硬件,一次只能打开一个阀门。硬件不允许您查询阀门的状态,因此需要在软件中处理。

当网络请求传入时,类似于“操作站1 15分钟”,我需要能够完成该命令,并等待适当的分钟数,然后再将引脚设置为off。每次执行都应该能够停止自己,我不想依靠外部命令关闭水,以免软件故障把我的院子变成池塘。

如果第二个命令在第一个操作时到达,我希望第一个操作终止自身,然后允许第二个命令运行。此终止将提前停止操作,记录它运行了多少分钟,等等。

我已经在Python中使用线程和队列编写了这篇文章,但是我想看看是否可以在Node中更干净地完成它。

我很好奇,我应该看看线程,产卵子进程,还是其他什么东西来实现我想要的呢?我需要一些非阻塞的,长时间运行的执行,可以监听信号被打断。

这是我的想法的一个概念,但是operateSprinkler函数会阻塞,因此需要修改或重写它。

代码语言:javascript
复制
net = require('net');

function operateSprinkler(minutes, station) {

    console.log('Operating Station ' + station + ' for ' + minutes + ' minutes.');

    var ms = minutes * 60 * 1000;
    var endTime = (new Date().getTime()) + ms;

    // Manipulate gpio pin to turn on sprinkler (pseudo-code here)
    gpio.on()

    while(new Date().getTime() < futureTime) {
        // Hang out until time expires
        // Listen for a signal that interrupts this function
    }
    else {
        gpio.off() // pseudo-code
    }

    console.log('Finished operating station.');
}

net.createServer(function(socket) {

    socket.on('data', function(data) {
        try {            
            var json = JSON.parse(data);
            // Make sure "minutes" and "station" were passed
            if (json.hasOwnProperty('minutes') && json.hasOwnProperty('station')) {
                operateSprinkler(json['minutes'], json['station']);
            }
        }
        catch(e) {
            console.log('Error. Invalid command.');            
        }
        socket.end();
    });

}).listen(5000);

console.log("Server running at port 5000\n");
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-22 21:15:54

通常,您需要重新处理代码来处理事件,无论是从计时器还是从洒水控制器。

在您提供的示例中,使用setTimeout,存储返回的timeoutId、洒水站和任何其他您需要访问的数据,以便以后可以取消它。

然后,替换您的operateSprinkler逻辑如下所示:

代码语言:javascript
复制
/*
 * current station is false if not running
 *
 * or {
 *     station:   stationid,
 *     duration:  time,
 *     start:     Date.now(),
 *     timeoutId: timeoutId
 * }
 */
var currentStation = false;

function operateSprinkler(minutes, station) {

    if(currentStation) {
        console.log('Cancelling station: ' + currentStation.station);

        gpio.off(); // Will need some way to look up by station...

        clearTimeout(currentStation.timeoutId);
    }

    var ms = minutes * 60 * 1000;
    var endTime = (new Date().getTime()) + ms;

    currentStation = {
        station: station,
        duration: ms,
        start: Date.now();
    };

    console.log('Operating Station ' + station + ' for ' + minutes + ' minutes.');

    // Manipulate gpio pin to turn on sprinkler (pseudo-code here)
    gpio.on()

    currentStation.timeoutId = setTimeout(function() {
        gpio.off();
        currentStation = false;

        console.log('Stopping station ' + currentStation.stationid);
        console.log('Finished operating station.');
    }, ms);
}
票数 1
EN

Stack Overflow用户

发布于 2013-07-22 20:59:00

只需使用setTimeout

代码语言:javascript
复制
var timer = setTimeout(stopSprinkler, 15_minutes_in_seconds);

您可以将这个计时器存储到一个变量中,如果/当另一个命令出现时,只需检查是否设置了这个变量。如果设置好了,您可以使用clearTimeout来停止计时器,并手动处理停止洒水器。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17797220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档