我正在遵循指导here(侦听SIGINT事件)以优雅地关闭我的Windows-8托管的node.js应用程序以响应Ctrl-C或服务器关闭。
但Windows没有SIGINT
。我也试过了process.on('exit')
,但这似乎迟到了做任何有用的事情。
在Windows上,此代码为我提供:错误:没有此类模块
process.on( 'SIGINT', function() {
console.log( "\ngracefully shutting down from SIGINT (Crtl-C)" )
// wish this worked on Windows
process.exit( )
})
在Windows上,此代码会运行,但太晚,无法做任何优雅的事情:
process.on( 'exit', function() {
console.log( "never see this log message" )
})
Windows上是否有SIGINT
等效事件?
答案 0 :(得分:128)
您必须使用readline模块并侦听SIGINT事件:
http://nodejs.org/api/readline.html#readline_event_sigint
if (process.platform === "win32") {
var rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
process.on("SIGINT", function () {
//graceful shutdown
process.exit();
});
答案 1 :(得分:14)
答案 2 :(得分:7)
除非您需要为其他任务导入“readline”,否则我建议在程序验证它在Windows上运行后导入“readline”。此外,对于那些可能不知道的人 - 这适用于Windows 32位和Windows 64位系统(将返回关键字“win32”)。感谢Gabriel的这个解决方案。
if (process.platform === "win32") {
require("readline")
.createInterface({
input: process.stdin,
output: process.stdout
})
.on("SIGINT", function () {
process.emit("SIGINT");
});
}
process.on("SIGINT", function () {
// graceful shutdown
process.exit();
});
答案 3 :(得分:4)
目前节点中仍然没有支持捕获Windows控制台控件事件,因此没有POSIX信号的等价物:
https://github.com/joyent/node/issues/1553
然而,tty module documentation确实给出了一个捕获按键的机制的示例,以便启动正常关闭,但是这只适用于 ctrl + c
var tty = require('tty');
process.stdin.resume();
tty.setRawMode(true);
process.stdin.on('keypress', function(char, key) {
if (key && key.ctrl && key.name == 'c') {
console.log('graceful exit of process %d', process.pid);
process.exit();
}
});
答案 4 :(得分:4)
现在它正常工作 on all platforms,包括Windows。
以下代码记录然后在Windows 10上正确终止:
process.on('SIGINT', () => {
console.log("Terminating...");
process.exit(0);
});
答案 5 :(得分:0)
由于node.js 0.8,keypress
事件不再存在。然而,有一个名为keypress的npm包重新实现了该事件。
使用npm install keypress
安装,然后执行以下操作:
// Windows doesn't use POSIX signals
if (process.platform === "win32") {
const keypress = require("keypress");
keypress(process.stdin);
process.stdin.resume();
process.stdin.setRawMode(true);
process.stdin.setEncoding("utf8");
process.stdin.on("keypress", function(char, key) {
if (key && key.ctrl && key.name == "c") {
// Behave like a SIGUSR2
process.emit("SIGUSR2");
} else if (key && key.ctrl && key.name == "r") {
// Behave like a SIGHUP
process.emit("SIGHUP");
}
});
}
答案 6 :(得分:0)
以上没有对我有用,所以解决方法是挂一个 readline 并从那里捕捉信号。
这是我的解决方案:
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
// Flag to be able to force the shutdown
let isShuttingDown = false;
// https://nodejs.org/api/readline.html
rl.on('SIGINT', async () => {
if (isShuttingDown) {
logger.info("Forcing shutdown, bye.");
process.exit();
} else {
if (!<yourIsCleanupNecessaryCheck>()) {
logger.info("No cleanup necessary, bye.");
process.exit();
} else {
logger.info("Closing all opened pages in three seconds (press Ctrl+C again to quit immediately and keep the pages opened) ...");
isShuttingDown = true;
await sleep(3000);
await <yourCleanupLogic>();
logger.info("All pages closed, bye.");
process.exit();
}
}
function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
它非常简单,它是异步的,并且适用于 MacOS 11.3 和 Windows 10(在撰写本文时)。