我正在从文本文件中读取ID并发出一些RESTful请求。它可以工作,但是当所有ID都已运行时,节点应用程序仍然在运行。
main.js:
var fs = require('fs');
var http = require('http');
var ids = fs.readFileSync('test.txt', { encoding: 'utf8' });
ids = ids.split('\n');
var options = {
hostname: 'internalhost',
port: 80,
path: '',
method: 'DELETE'
};
for (var i = 0; i < ids.length; i++) {
options.path = '/thing/' + ids[i];
console.log('Deleting thing ' + ids[i]);
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
});
req.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
req.end();
}
请求成功完成但在最后一个请求后,应用程序继续运行。我在打印响应的状态代码后立即尝试添加res.end()
,但后来发现res
没有方法end
的错误。
这里发生了什么?
答案 0 :(得分:3)
看来你是suffering from a side-effect of HTTP keep-alives。当TCP连接打开时,节点不会退出,HTTP Agent
会使TCP连接无限期地打开。
您已经提到保持活动对您有益,因此您的选择有限。
只需禁用Agent
即可停用保持活动,因此这不是一个选项。
您可以手动管理和跟踪您的请求,完成所有请求后,请致电process.exit
。然而,我不喜欢这样,因为它是一种相当钝的乐器。如果您正在运行其他异步操作(例如数据库调用),则可能会在这些操作完成之前意外终止您的应用程序。
您可以手动管理和跟踪您的请求。完成所有操作后,您可以遍历Agent
实例的sockets
属性并关闭所有延迟套接字。 (警告:calling close
on an already closed socket throws。)
这是一种更安全的方法,因为在应用程序退出之前,其他未完成的操作将被允许完成。
您可以升级到节点≥0.11.4。 (实际上,您可能希望等到释放0.12稳定版。)下一个节点版本有一个greatly improved Agent
implementation unref
个空闲套接字保留在Agent
的连接池中。换句话说,如果唯一的开放TCP连接是被保留以作为保持连接的重用连接,则节点可以退出。
您还可以从不稳定分支中删除new Agent
implemention并将其用于应用的请求,而不是您的节点版本提供的默认Agent
。 (这可能就是我要做的。)
答案 1 :(得分:2)
节点才会终止。在这种情况下,我认为连接仍处于打开状态,因此您可以通过调用res.socket.end()
或res.destroy()
或@ExplosionPills建议手动销毁它,只需在所有请求完成后调用process.exit
即可。您可以使用async
模块来帮助您实现此目标。