Що таке еквівалент Windows.process.on ('SIGINT') у node.js?


84

Я слідую наведеним тут вказівкам (прослуховування SIGINTподій) для витонченого вимкнення моєї програми node.js, розміщеної у Windows-8, у відповідь на вимкнення 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" )
})

Чи існує SIGINTеквівалентна подія в Windows?


Ця проблема випадково виникла у мене сьогодні, і я думаю, що це пов'язано з самим модулем readline. Я не міг провести жодного тестування, але оскільки я додав цей модуль, у мене почалася проблема.
Sv443

Відповіді:


149

Вам потрібно скористатися модулем 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();
});

найкраще оновлення, дякую! встановити це як відповідь, оскільки попередня відповідь (прослуховування натискання клавіші) більше не працює.
pappadog

44
Це смішно. Чому це не обробляється ядром вузла?
балуптон

3
Тому що, коли ви слухаєте stdin, процес ніколи не закінчується, поки ви явно не надішлете сигнал SIGINT.
Габріель Ламас

2
Тому вам потрібно надіслати випадкове повідомлення від батьків дитині, наприклад: "ЗНАК".
Габріель Ламас

8
Схоже, це було вирішено досить давно: github.com/nodejs/node-v0.x-archive/issues/5054
SimonSimCity

23

Я не впевнений, коли, але на вузлі 8.x та Windows 10 оригінальний код запитання просто працює зараз.

process.on( "SIGINT", function() {
  console.log( "\ngracefully shutting down from SIGINT (Crtl-C)" );
  process.exit();
} );

process.on( "exit", function() {
  console.log( "never see this log message" );
} );

setInterval( () => console.log( "tick" ), 2500 );

введіть тут опис зображення

також працює з командним рядком Windows.


Я це теж помітив. Windows 7 є для мене головною проблемою
Грегорі Новаковський,

Цей метод працює для мене з Node 8.11.1 у Windows 7, але я запускав його з оболонки git bash. Думав, спочатку спробую простий спосіб, і це спрацювало.
user944849

7

Якщо вам не потрібен імпорт "readline" для інших завдань, я б запропонував імпортувати "readline", як тільки програма перевірить, що вона працює в Windows. Крім того, для тих, хто може не знати - це працює як на 32-розрядної Windows, так і на 64-розрядної системи Windows (що повертає ключове слово "win32"). Дякую за це рішення Габріель.

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();
});

5

У наш час він просто працює на всіх платформах , включаючи Windows.

Наступні журнали коду, а потім закінчуються належним чином у Windows 10:

process.on('SIGINT', () => {
    console.log("Terminating...");
    process.exit(0);
});

2
Це НЕ працює для мене під cygwin. Використовуючи останню Windows 10 (автоматичне оновлення), версія вузла 8.11.4. Під "це НЕ працює" я маю на увазі, що 1) процес завершується, але 2) повідомлення не реєструється на консолі та 3) Створені з'єднання HTTP не припиняються. Однак слід додати, що я пробував це під PowerShell, і там він працює як слід. Але я перейшов на cygwin, оскільки PowerShell має погану команду curl. Проклятий!
Джон Дейган

2
Сьогодні він перестав працювати для мене без видимих ​​причин (ніяких оновлень взагалі), і я досі не знаю чому. Прийнята відповідь це виправила.
Sv443

4

В даний час у вузлі ще немає підтримки для захоплення подій управління консоллю Windows, тому немає еквівалентів сигналам POSIX:

https://github.com/joyent/node/issues/1553

Однак документація модуля tty дає приклад механізму фіксації натискань клавіш, щоб ініціювати витончене вимкнення, але тоді це працює лише для 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();
  }
});

Дякую, шукаючи цю інформацію, це прийнятна заміна для мене, якщо я можу реалізувати її на сервері для CTRL + C. +1 (Але .. Будь-яка ідея, чи вплине це на продуктивність, додаючи слухачів подій до процесу?)
Кори Гросс

Я спробував це зробити, але коли на моєму сервері запущений ігровий цикл stdin, здається, недоступний, CTRL + C не працює, коли я використовую вищезазначене.
Кори Гросс

0

З node.js 0.8 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");
        }
    });
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.