正常关闭节点expressjs不工作 [英] Graceful closing of node expressjs not working

查看:185
本文介绍了正常关闭节点expressjs不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的问题。我试图关闭一个expressjs nodejs服务器,以便当前请求完成他们的响应和新的请求完全被拒绝。我已经把我的代码弄到了只是裸骨骼,这样更容易理解:

I have a simple problem. I'm trying to shutdown an expressjs nodejs server so that current requests finish their responses and new requests get rejected altogether. I've wittled down my code to just the bare bones so that it'd be easier to understand:

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



<基本上,我提出两个请求。第一个需要8秒,服务器立即关闭。因此,任何未来的请求都应该被拒绝。第二个请求,但是,仍然通过。控制台输出:

So essentially, I make two requests. The first one takes 8 seconds, and the server is closed immediately. So any future requests should be rejected. The second request, however, still gets through. Console output:

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

如果您可以解释发生了什么,我会很感激。

If you could explain what's going on I would appreciate it.

更新:

Per Benjamin的回应,我试过他建议的测试代码,它的工作原理。问题出现在浏览器中。我编辑了原始服务器:

Per Benjamin's response, I tried the test code he suggested, and it worked as expected. The problem is in the browser. I edited the original server:

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建议,你得到预期的输出:

Note the changes around server.close. When I run the test code Benjamin suggested, you get the expected output:

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

但是当我在chrome中打开两个标签页时,请先请求,然后等待几秒钟,然后请求第二,我得到这个输出:

But when I open two tabs in chrome, request the first, wait a few seconds, then request the second, I get this output:

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

没有process.exit,'closed'回调永远不会调用。种类奇怪的行为。

And without the process.exit, the 'closed' callback never gets called. Kind of weird behavior.

感谢您的帮助。

推荐答案

Express中的此函数 .close()基于 .close 在节点的http模块中,该节点基于 .close

This function .close() in express is based on .close in the http module in node which is based on the .close in the net module in nodejs.

让我们看看API是什么。

Let's see what the API says.


停止服务器接受新连接并保持现有连接。此函数为异步,当所有连接结束并且服务器发出关闭事件时,服务器终止关闭。或者,您可以传递一个回调以侦听关闭事件。

Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event. Optionally, you can pass a callback to listen for the 'close' event.

这意味着你可能在同一个节点上运行测试代码,并且关闭没有得到运行的机会。

This means it's possible you were running the testing code on the same instance of node and close didn't get a chance to run.

此外,setTimeout不准确,有可能是一个setTimeout 8000毫秒将在8015毫秒7980

Also, setTimeout is not accurate, it's possible that a setTimeout for 8000 miliseconds will fire after 8015 miliseconds of 7980 miliseconds.

当我运行以下代码从一个不同的节点程序测试你的代码:

When I run the following code to test your code from a different node program:

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 这是我期望的

The other window running the client throws ECONNREFUSED which is what I'd expect

这篇关于正常关闭节点expressjs不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆