Gol*_*den 51 connection http keep-alive node.js
我有一个包含http(s)服务器的Node.js应用程序.
在特定情况下,我需要以编程方式关闭此服务器.我目前正在做的是调用它的close()函数,但这没有用,因为它等待任何保持活动的连接首先完成.
因此,基本上,这会关闭服务器,但仅在最短120秒的等待时间之后.但我希望服务器立即关闭 - 即使这意味着与当前处理的请求分手.
我不能做的是一个简单的
process.exit();
Run Code Online (Sandbox Code Playgroud)
因为服务器只是应用程序的一部分,应用程序的其余部分应该保持运行.我正在寻找的是概念上的东西,例如类似的server.destroy();东西.
我怎么能实现这个目标?
PS:通常需要连接的保持活动超时,因此减少此时间不是可行的选择.
Gol*_*den 67
诀窍是你需要订阅服务器的connection事件,它为你提供了新连接的套接字.你需要记住这个套接字,然后在调用之后直接server.close()使用它来销毁该套接字socket.destroy().
此外,如果套接字的close事件自然离开,则需要监听套接字的事件以将其从数组中删除,因为它的保持活动超时确实已用完.
我编写了一个小示例应用程序,您可以使用它来演示此行为:
// Create a new server on port 4000
var http = require('http');
var server = http.createServer(function (req, res) {
res.end('Hello world!');
}).listen(4000);
// Maintain a hash of all connected sockets
var sockets = {}, nextSocketId = 0;
server.on('connection', function (socket) {
// Add a newly connected socket
var socketId = nextSocketId++;
sockets[socketId] = socket;
console.log('socket', socketId, 'opened');
// Remove the socket when it closes
socket.on('close', function () {
console.log('socket', socketId, 'closed');
delete sockets[socketId];
});
// Extend socket lifetime for demo purposes
socket.setTimeout(4000);
});
// Count down from 10 seconds
(function countDown (counter) {
console.log(counter);
if (counter > 0)
return setTimeout(countDown, 1000, counter - 1);
// Close the server
server.close(function () { console.log('Server closed!'); });
// Destroy all open sockets
for (var socketId in sockets) {
console.log('socket', socketId, 'destroyed');
sockets[socketId].destroy();
}
})(10);
Run Code Online (Sandbox Code Playgroud)
基本上,它的作用是启动一个新的HTTP服务器,从10到0计数,并在10秒后关闭服务器.如果尚未建立连接,则服务器立即关闭.
如果已建立连接且仍处于打开状态,则会将其销毁.如果它已经自然死亡,那么此时只打印出一条消息.
Jon*_*ray 17
我找到了一种方法来做到这一点,而无需跟踪连接或不得不强制关闭.我不确定它在Node版本中的可靠性如何,或者如果对此有任何负面影响,但它似乎对我正在做的事情完全正常.诀窍是setImmediate在调用close方法后立即发出"关闭"事件.这样工作如下:
server.close(callback);
setImmediate(function(){server.emit('close')});
Run Code Online (Sandbox Code Playgroud)
至少对我来说,这最终会释放端口,这样我就可以在调用回调时启动一个新的HTTP(S)服务(这几乎是即时的).现有连接保持开放.在更新Let的加密证书后,我正在使用它来自动重启HTTPS服务.
如果你需要在关闭服务器后保持进程存活,那么Golo Roden的解决方案可能是最好的.
但是,如果您正在关闭服务器作为正常关闭进程的一部分,那么您只需要:
var server = require('http').createServer(myFancyServerLogic);
server.on('connection', function (socket) {socket.unref();});
server.listen(80);
function myFancyServerLogic(req, res) {
req.connection.ref();
res.end('Hello World!', function () {
req.connection.unref();
});
}
Run Code Online (Sandbox Code Playgroud)
基本上,服务器使用的套接字只会在实际处理请求时使进程保持活动状态.虽然他们只是懒散地坐在那里(因为保持活跃的连接),但是server.close()只要没有其他任何东西可以让这个过程保持活跃,他就会关闭这个过程.如果您需要在服务器关闭后执行其他操作,作为正常关闭的一部分,您可以挂钩process.on('beforeExit', callback)以完成正常的关闭过程.
小智 7
所述https://github.com/isaacs/server-destroy库提供了一种简单的方法来destroy()与所述问题所期望的行为的服务器(通过跟踪打开的连接和销毁它们中的每对服务器破坏,在其他的答案描述).
小智 5
正如其他人所说,解决方案是跟踪所有打开的套接字并手动关闭它们。我的 node 包killable可以为您做到这一点。一个示例(使用 express,但您可以在任何http.server实例上调用 use killable ):
var killable = require('killable');
var app = require('express')();
var server;
app.route('/', function (req, res, next) {
res.send('Server is going down NOW!');
server.kill(function () {
//the server is down when this is called. That won't take long.
});
});
var server = app.listen(8080);
killable(server);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
47254 次 |
| 最近记录: |