26

Express.jsサービスがによって停止されたときに、いくつかの便利なことを行う必要がありますSIGINT。Express.jsバージョン3.0.6を使用すると、これが機能するはずだと理解しています。

var express = require('express');

var app = express();
var server = app.listen(3000);

process.on('SIGINT', function() {
  console.log('Do something useful here.');
  server.close();
});

SIGINTしかし、 (Control- C)を2回発行しない限り、このプロセスではBashプロンプトが返されません。

$ node problem.js 
^CDo something useful here.
^CDo something useful here.

net.js:1046
    throw new Error('Not running');
          ^
Error: Not running
    at Server.close (net.js:1046:11)
    at process.<anonymous> (/path/to/problem.js:8:10)
    at process.EventEmitter.emit (events.js:93:17)
    at SignalWatcher.startup.processSignalHandlers.process.on.process.addListener.w.callback (node.js:486:45)
$

もう1つの注意点。このExpress.jsサービスを開始し、リクエストを送信しないと、SIGINT正しく終了します。

明らかに、私がここで見逃している基本的なものがありますか?

4

3 に答える 3

35

ハンドラーをキャッチすることで、プロセスを終了するというデフォルトの動作SIGINTを防ぐことができます。2回目に使用すると、キャッチされない例外がスローされるため、プロセスが終了します。Ctrl+Cserver.close

ハンドラーprocess.exit()の最後にを追加するだけで、プロセスを正常に終了できます。SIGINT

于 2013-01-17T04:47:10.423 に答える
12

質問が完全に(または正しく)答えられておらず、人々がまだこの答えを見つける可能性があるため、オールディーズを復活させる。

あなたの質問の重要な部分は次のとおりです。

もう1つの注意点。このExpress.jsサービスを開始し、リクエストを送信しない場合、SIGINTは正しく終了します。明らかに、私がここで見逃している根本的な何かがありますか? `

不足しているのは、デフォルトでExpressが再利用のために接続を開いたままにする(HTTPキープアライブ)ことです。したがって、(最近の)リクエストがあった場合でも、イベントループに何かがあり、それがアプリが閉じない理由です。

使用process.exit()は機能しますが、別の^ Cを送信するようなものであり、他に何かが開いているという事実を隠す可能性があります(データベース接続など)。イベントループに何も残っていない場合は、アプリを閉じる必要があります。

そこで、私はあなたの例を変更し、接続に5秒のキープアライブを設定して、妥当な時間内に正常にシャットダウンするようにしました。

var express = require('express');

var serverPort = 3000;
var app = express();
var server = app.listen(serverPort);


// HTTP Keep-Alive to a short time to allow graceful shutdown
server.on('connection', function (socket) {
  socket.setTimeout(5 * 1000);
});

// Handle ^C
process.on('SIGINT', shutdown);

// Do graceful shutdown
function shutdown() {
  console.log('graceful shutdown express');
  server.close(function () {
    console.log('closed express');
  });
}

console.log('running server: http://localhost:' + serverPort);

于 2017-06-28T05:18:11.240 に答える
8

私はこのコードを使用しています:

server.close(() => {
  process.exit(0)
})
于 2017-04-26T14:19:40.910 に答える