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.