长时间运行的Node.js服务,可连续发出http请求
我开始开发我的第一个Node.js应用程序,遇到了无法确定的内存泄漏问题。我希望应用程序以一种持续运行、轮询和端点的方式充当服务。我想我可能遗漏了什么。该项目的想法是让一个节点应用程序不断地向一个Arduino板发出http请求,我已经用一个web服务器连接到我的网络。网络板使用一些JSON或XML响应请求,这些JSON或XML表示连接到其上的传感器的状态。node应用程序的想法是记录传感器的变化,然后发射这些变化最终将被另一个electron项目消耗 节点应用程序当前分为两个模块: 代理:对arduino web服务器上的不同端点进行http调用:长时间运行的Node.js服务,可连续发出http请求,node.js,Node.js,我开始开发我的第一个Node.js应用程序,遇到了无法确定的内存泄漏问题。我希望应用程序以一种持续运行、轮询和端点的方式充当服务。我想我可能遗漏了什么。该项目的想法是让一个节点应用程序不断地向一个Arduino板发出http请求,我已经用一个web服务器连接到我的网络。网络板使用一些JSON或XML响应请求,这些JSON或XML表示连接到其上的传感器的状态。node应用程序的想法是记录传感器的变化,然后发射这些变化最终将被另一个electron项目消耗 节点应用程序当前分为两个模块: 代理:对a
var http = require('http'),
KeepAliveAgent = require('keep-alive-agent');
var controllerRequestOpts = {};
function send(path, cb){
var response = '';
//build the request
var request = controllerRequestOpts;
request.path = path;
//make the call to the controller
http.get(request, function(res){
res.on('data', function(chunk){
response += chunk;
});
res.on('end', function(){
cb(null, response);
});
})
.on('error',function(e){
cb(e, null);
});
}
module.exports = function(controllerOptions){
controllerOptions.port = controllerOptions.port || 2222;
controllerRequestOpts = controllerOptions;
controllerRequestOpts.agent = new KeepAliveAgent();
return{
//JSON
queryJson: function(cb){
send('/json', cb);
},
//XML
queryXml: function(cb){
send('/xml', cb);
}
//Additional endpoints
}
}
runner:使用提供的间隔永久循环,对arduino进行代理调用
var proxy = require('proxy');
var Watcher = require('./watcher');
var timer;
var toUpdate;
function initProxy(controllerParams){
proxy = proxy(controllerParams);
Watcher = new Watcher();
}
function startListening(startOptions){
var query;
//determine the query and callback functions based off configuration
query = startOptions.queryType === 'json'
? proxy.queryJson
: proxy.queryXml;
toUpdate = startOptions.queryType === 'json'
? Watcher.updateLatestJson
: Watcher.updateLatestXml;
//Start running and making requests every 15 seconds
timer = setInterval(function(){
query(handleResponse);
},startOptions.queryInterval);
}
function handleResponse(err, resp){
if(err){
console.log('ERROR: ' + err);
}
else{
toUpdate.call(Watcher, resp);
}
}
function stopListening(){
clearInterval(timer);
process.exit();
}
var runner = {
connect: function(controllerParams){
initProxy(controllerParams);
},
start: function(startOptions){
startListening(startOptions);
return Watcher;
},
stop: function(){
stopListening();
}
};
module.exports = runner;
我有一个“Watcher”模块,它只是一个构造函数,将更改发送回调用应用程序,如下所示:
var runner = require('./index');
var controllerSettings = {
hostname: '192.168.1.150',
port:2222
}
var startOptions = {
queryType: 'json',
queryInterval: 15000
}
runner.connect(controllerSettings);
var watcher = runner.start(startOptions);
watcher.on('P1Changed', printParams)
一切正常,但随着应用程序的运行,节点进程的内存使用量不断增加。我想知道我是否错误地使用了http模块,或者运行程序是否不应该执行setInterval。是否有一种标准方法可以将此类应用程序作为“服务”运行,而不是像“服务器”一样连续发送多个HTTP请求会导致节点创建巨大的TLSWrap对象,GC在几分钟内无法清除这些对象
如果您希望反复向同一主机发送数据,则需要打开TCP连接(流),而不是使用开销巨大的HTTP请求。因此,如果我理解,我应该使用net模块打开与arduino主机的套接字连接,编写HTTP请求,然后解析响应?有没有办法保持套接字打开以持续写入请求?这是否会阻止控制器在套接字打开时响应其他正常http请求或将数据发布到其他服务?