1

簡単な問題があります。現在のリクエストが応答を終了し、新しいリクエストが完全に拒否されるように、expressjs nodejs サーバーをシャットダウンしようとしています。理解しやすいように、コードを最小限の骨だけに絞り込みました。

express = require("express")
http = require("http")
app = express()

app.configure ->
    app.set "port", process.env.PORT or 3000
    app.use app.router

ran = false
app.get '/testrun', (req, res)->
    console.log "received request"
    if ran
        res.json
            shouldnt: 'have gotten here'
    else
        ran = true
        setTimeout ->
            res.json
                response: 'fail!'
        , 8000
        console.log 'server closing'
        server.close()
        setTimeout ->
            process.exit()
        , 10000

server = http.createServer(app)
server.listen app.get("port"), ->
    console.log "Express server listening on port " + app.get("port")

基本的に、私は 2 つの要求を行います。最初の 1 つは 8 秒かかり、サーバーはすぐに閉じられます。したがって、今後のリクエストは拒否する必要があります。ただし、2 番目の要求は引き続き通過します。コンソール出力:

$> Express server listening on port 3000
received request
server closing
received request

何が起こっているのか説明していただければ幸いです。

アップデート:

Benjamin の回答に従って、彼が提案したテスト コードを試してみたところ、期待どおりに動作しました。問題はブラウザにあります。元のサーバーを編集しました:

express = require("express")
http = require("http")
app = express()

app.configure ->
    app.set "port", process.env.PORT or 3000
    app.use app.router

ran = false
app.get '/testrun', (req, res)->
    console.log "received request"
    if ran
        res.json
            shouldnt: 'have gotten here'
    else
        ran = true
        setTimeout ->
            res.json
                response: 'fail!'
        , 5000
        console.log 'server closing' # changes here
        server.close ->
            console.log 'closed!'

server = http.createServer(app)
server.listen app.get("port"), ->
    console.log "Express server listening on port " + app.get("port")

server.close に関する変更に注意してください。Benjamin が提案したテスト コードを実行すると、期待どおりの出力が得られます。

$>Express server listening on port 3000
received request
server closing
closed!

しかし、Chrome で 2 つのタブを開き、最初のタブをリクエストし、数秒待ってから 2 番目のタブをリクエストすると、次の出力が得られます。

$>Express server listening on port 3000
received request
server closing
received request

また、process.exit がないと、「closed」コールバックが呼び出されることはありません。ちょっと変な振る舞い。

ご協力いただきありがとうございます。

4

1 に答える 1

2

.close()Express のこの関数は、nodejs の net モジュールに.close基づいている node の http モジュールに基づいてい ます。.close

API の内容を見てみましょう。

サーバーが新しい接続を受け入れるのを停止し、既存の接続を維持します。この関数は非同期です。すべての接続が終了し、サーバーが「close」イベントを発行すると、サーバーは最終的に閉じられます。オプションで、'close' イベントをリッスンするコールバックを渡すことができます。

これは、ノードの同じインスタンスでテスト コードを実行していて、close実行する機会がなかった可能性があることを意味します。

また、setTimeout は正確ではありません。8000 ミリ秒の setTimeout が 7980 ミリ秒のうち 8015 ミリ秒後に起動する可能性があります。

次のコードを実行して、別のノード プログラムからコードをテストすると:

http = require("http")
http.get "http://localhost:3000/testrun"
setTimeout http.get.bind(http,"http://localhost:3000/testrun"), 8000
setTimeout http.get.bind(http,"http://localhost:3000/testrun"), 9000

私は得る

$ coffee test.coffee
Express server listening on port 3000
received request
server closing

クライアントを実行している他のウィンドウがスローしますECONNREFUSED。これは私が期待するものです

于 2013-05-22T18:34:54.513 に答える