我有一个简单的问题。我正在尝试关闭一个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")
基本上,我提出了两个请求。第一个需要8秒,服务器立即关闭。所以任何未来的请求都应该被拒绝。然而,第二个请求仍然可以通过。控制台输出:
$> Express server listening on port 3000
received request
server closing
received request
如果你能解释一下发生了什么,我会很感激。
更新:
Per 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中打开两个标签时,请求第一个,等待几秒钟,然后请求第二个,我得到这个输出:
$>Express server listening on port 3000
received request
server closing
received request
如果没有process.exit,'封闭'回调永远不会被调用。一种奇怪的行为。
感谢您的帮助。
答案 0 :(得分:2)
express中的此函数.close()
基于节点中http模块中的.close
,它基于nodejs中net模块中的.close
。
让我们看看API的用途。
停止服务器接受新连接并保留现有连接。此功能是异步,当所有连接都结束且服务器发出“关闭”事件时,服务器最终会关闭。或者,您可以传递回调以侦听“关闭”事件。
这意味着你可能在同一个节点实例上运行测试代码而close
没有机会运行。
此外,setTimeout不准确,可能会在80毫秒7980毫秒后触发8000毫秒的setTimeout。
当我运行以下代码以从不同的节点程序测试代码时:
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
这是我期望的