Windows tương đương với process.on ('SIGINT') trong node.js là gì?


84

Tôi đang làm theo hướng dẫn tại đây (lắng nghe các SIGINTsự kiện) để tắt ứng dụng node.js được lưu trữ trên Windows-8 của mình một cách duyên dáng để phản hồi Ctrl+ Choặc tắt máy chủ.

Nhưng Windows không có SIGINT. Tôi cũng đã cố gắng process.on('exit'), nhưng điều đó dường như đã muộn để làm bất cứ điều gì hiệu quả.

Trên Windows, mã này cho tôi: Lỗi: Không có mô-đun như vậy

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

Trên Windows, mã này chạy, nhưng đã quá muộn để làm bất cứ điều gì duyên dáng :

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

SIGINTsự kiện tương đương trên Windows không?


Vấn đề này ngẫu nhiên xảy ra với tôi ngày hôm nay và tôi nghĩ rằng nó có liên quan gì đó đến chính mô-đun readline. Tôi không thể thực hiện bất kỳ thử nghiệm nào nhưng kể từ khi tôi thêm mô-đun này, tôi bắt đầu gặp sự cố.
Sv443

Câu trả lời:


148

Bạn phải sử dụng mô-đun dòng đọc và lắng nghe sự kiện 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();
});

cập nhật tuyệt vời nhất, cảm ơn! cài đặt này làm câu trả lời vì câu trả lời trước đó (lắng nghe khi nhấn phím) không còn hoạt động.
pappadog

44
Chuyện này thật vớ vẩn. Tại sao điều này không được xử lý bởi lõi nút?
balupton

3
Bởi vì khi bạn nghe stdin, quá trình này không bao giờ kết thúc cho đến khi bạn gửi tín hiệu SIGINT một cách rõ ràng.
Gabriel Llamas

2
Do đó, bạn cần gửi một tin nhắn ngẫu nhiên từ cha mẹ đến con cái, ví dụ: "SIGINT".
Gabriel Llamas

8
Ngoại hình như thế này đã giải quyết khá một thời gian trước: github.com/nodejs/node-v0.x-archive/issues/5054
SimonSimCity

23

Tôi không chắc là khi nào, nhưng trên nút 8.x và trên Windows 10, mã câu hỏi ban đầu chỉ hoạt động ngay bây giờ.

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

nhập mô tả hình ảnh ở đây

cũng hoạt động với dấu nhắc lệnh của windows.


Tôi cũng nhận thấy điều này. Windows 7 là một vấn đề lớn đối với tôi đây
Gregory Nowakowski

Phương pháp này phù hợp với tôi với Node 8.11.1 trên Windows 7 - nhưng tôi đang chạy nó từ trình bao git bash. Tôi nghĩ tôi sẽ thử cách đơn giản trước và nó đã hoạt động.
user944849

7

Trừ khi bạn cần nhập "dòng đọc" cho các tác vụ khác, tôi khuyên bạn nên nhập "dòng đọc" khi chương trình đã xác minh rằng nó đang chạy trên Windows. Ngoài ra, đối với những người có thể không biết - điều này hoạt động trên cả hệ thống Windows 32 bit và Windows 64 bit (sẽ trả về từ khóa "win32"). Cảm ơn vì giải pháp này 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

Ngày nay nó chỉ hoạt động trên tất cả các nền tảng , bao gồm cả Windows.

Đoạn mã sau ghi nhật ký và sau đó kết thúc đúng cách trên Windows 10:

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

2
Điều này KHÔNG làm việc cho tôi theo cygwin. Sử dụng Windows 10 mới nhất (cập nhật tự động), phiên bản nút 8.11.4. Bởi "nó KHÔNG hoạt động" Ý tôi là 1) quá trình kết thúc, nhưng 2) thông báo không được ghi vào bảng điều khiển và 3) các kết nối HTTP được tạo không bị tắt. Tuy nhiên, tôi nên thêm rằng tôi đã thử nó trong PowerShell và nó hoạt động như mong đợi ở đó. Nhưng tôi đã chuyển sang cygwin vì PowerShell có lệnh curl không tốt. Em yêu!
John Deighan

2
Nó đã ngừng hoạt động đối với tôi hôm nay mà không có lý do rõ ràng (không có bản cập nhật nào cả) và tôi vẫn không biết tại sao. Câu trả lời được chấp nhận đã sửa nó.
Sv443,

4

Hiện tại vẫn không có hỗ trợ trong nút để nắm bắt các sự kiện điều khiển bảng điều khiển windows, vì vậy không có tín hiệu tương đương với tín hiệu POSIX:

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

Tuy nhiên, tài liệu về mô-đun tty đưa ra một ví dụ về cơ chế ghi lại các lần nhấn phím để bắt đầu tắt máy một cách duyên dáng, nhưng sau đó điều này chỉ hoạt động đối với 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();
  }
});

Cảm ơn, tôi đã tìm kiếm thông tin này, đây là sự thay thế có thể chấp nhận được đối với tôi miễn là tôi có thể triển khai nó trên máy chủ cho CTRL + C. +1 (Nhưng .. Bất cứ ý tưởng cho dù điều này sẽ ảnh hưởng hiệu suất bằng cách thêm người nghe sự kiện về quy trình?)
Cory Gross

Tôi đã thử thực hiện việc này, nhưng khi máy chủ của tôi đang chạy, stdin của vòng lặp trò chơi dường như không khả dụng, CTRL + C không hoạt động khi tôi sử dụng ở trên.
Cory Gross

0

Kể từ node.js 0.8, keypresssự kiện không còn tồn tại. Tuy nhiên, có một gói npm được gọi là keypress thực hiện lại sự kiện.

Cài đặt với npm install keypress, sau đó làm một cái gì đó như:

// 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");
        }
    });
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.