Jaki jest odpowiednik process.on ('SIGINT') w node.js w systemie Windows?


85

Postępuję zgodnie ze wskazówkami tutaj (nasłuchiwanie SIGINTzdarzeń), aby bezpiecznie zamknąć moją aplikację node.js hostowaną w systemie Windows-8 w odpowiedzi na Ctrl+ Club zamknięcie serwera.

Ale Windows nie ma SIGINT. Ja też próbowałem process.on('exit'), ale wydaje mi się , że jest to za późno, aby zrobić cokolwiek produktywnego.

W systemie Windows ten kod daje mi: Błąd: nie ma takiego modułu

process.on( 'SIGINT', function() {
  console.log( "\ngracefully shutting down from  SIGINT (Crtl-C)" )
  // wish this worked on Windows
  process.exit( )
})

W systemie Windows ten kod działa, ale jest za późno, aby zrobić cokolwiek wdzięcznego :

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

Czy istnieje SIGINTrównoważne zdarzenie w systemie Windows?


Ten problem przypadkowo pojawił się dziś u mnie i myślę, że ma coś wspólnego z samym modułem readline. Nie mogłem wykonać żadnych testów, ale odkąd dodałem ten moduł, zacząłem mieć problem.
Sv443

Odpowiedzi:


151

Musisz użyć modułu readline i nasłuchiwać zdarzenia 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();
});

najdoskonalsza aktualizacja, dzięki! ustawienie tej odpowiedzi jako poprzedniej odpowiedzi (nasłuchiwanie naciśnięcia klawisza) już nie działa.
pappadog

45
To jest niedorzeczne. Dlaczego nie jest to obsługiwane przez rdzeń węzła?
balupton

3
Ponieważ kiedy słuchasz stdin, proces nigdy się nie kończy, dopóki nie wyślesz jawnie sygnału SIGINT.
Gabriel Llamas

2
Dlatego należy wysłać dziecku losową wiadomość od rodzica, na przykład: „SIGINT”.
Gabriel Llamas

8
Wygląda na to, że problem ten został rozwiązany jakiś czas temu: github.com/nodejs/node-v0.x-archive/issues/5054
SimonSimCity

23

Nie jestem pewien, kiedy, ale w węźle 8.x i Windows 10 oryginalny kod zapytania po prostu teraz działa.

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

wprowadź opis obrazu tutaj

działa również z wierszem poleceń systemu Windows.


Ja też to zauważyłem. Windows 7 to dla mnie poważny problem
Gregory Nowakowski

Ta metoda działa dla mnie z Node 8.11.1 w systemie Windows 7 - ale uruchamiałem ją z powłoki git bash. Pomyślałem, że najpierw spróbuję prostego sposobu i zadziałało.
user944849

7

O ile nie potrzebujesz importu „readline” do innych zadań, sugerowałbym zaimportowanie „readline” po sprawdzeniu, że program działa w systemie Windows. Dodatkowo dla tych, którzy mogą być nieświadomi - działa to zarówno na 32-bitowych, jak i 64-bitowych systemach Windows (co zwróci słowo kluczowe „win32”). Dzięki za to rozwiązanie 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();
});

5

Obecnie działa tylko na wszystkich platformach , w tym Windows.

Poniższy kod rejestruje się, a następnie kończy poprawnie w systemie Windows 10:

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

2
To NIE działa dla mnie pod cygwinem. Korzystając z najnowszego systemu Windows 10 (automatyczne aktualizacje), wersja węzła 8.11.4. Przez „to NIE działa” mam na myśli, że 1) proces się kończy, ale 2) wiadomość nie jest logowana do konsoli i 3) utworzone połączenia HTTP nie są zamykane. Powinienem jednak dodać, że wypróbowałem go pod PowerShell i działa tam zgodnie z oczekiwaniami. Ale przełączyłem się na cygwin, ponieważ PowerShell ma złe polecenie curl. Cerować!
John Deighan,

2
Przestał działać dla mnie właśnie dzisiaj bez wyraźnego powodu (żadnych aktualizacji) i nadal nie wiem dlaczego. Zaakceptowana odpowiedź rozwiązała problem.
Sv443

4

Obecnie w węźle nadal nie ma obsługi przechwytywania zdarzeń sterujących konsoli systemu Windows, więc nie ma odpowiedników dla sygnałów POSIX:

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

Jednak dokumentacja modułu tty podaje przykład mechanizmu przechwytywania naciśnięć klawiszy w celu zainicjowania wdzięcznego zamknięcia, ale wtedy działa to tylko dla 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();
  }
});

Dzięki, szukałem tych informacji, jest to dla mnie akceptowalne zastąpienie, o ile mogę zaimplementować to na serwerze dla CTRL + C. +1 (Ale… Czy masz pomysł, czy wpłynie to na wydajność, dodając do procesu słuchaczy wydarzeń?)
Cory Gross,

Próbowałem to zrobić, ale kiedy mój serwer uruchamia pętlę gry, stdin wydaje się być niedostępny, CTRL + C nie działa, gdy używam powyższego.
Cory Gross,

0

Od node.js 0.8 keypresszdarzenie już nie istnieje. Istnieje jednak pakiet npm o nazwie keypress, który ponownie implementuje zdarzenie.

Zainstaluj za pomocą npm install keypress, a następnie zrób coś takiego:

// 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");
        }
    });
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.