长时间运行的Node.js服务,可连续发出http请求

长时间运行的Node.js服务,可连续发出http请求,node.js,Node.js,我开始开发我的第一个Node.js应用程序,遇到了无法确定的内存泄漏问题。我希望应用程序以一种持续运行、轮询和端点的方式充当服务。我想我可能遗漏了什么。该项目的想法是让一个节点应用程序不断地向一个Arduino板发出http请求,我已经用一个web服务器连接到我的网络。网络板使用一些JSON或XML响应请求,这些JSON或XML表示连接到其上的传感器的状态。node应用程序的想法是记录传感器的变化,然后发射这些变化最终将被另一个electron项目消耗 节点应用程序当前分为两个模块: 代理:对a

我开始开发我的第一个Node.js应用程序,遇到了无法确定的内存泄漏问题。我希望应用程序以一种持续运行、轮询和端点的方式充当服务。我想我可能遗漏了什么。该项目的想法是让一个节点应用程序不断地向一个Arduino板发出http请求,我已经用一个web服务器连接到我的网络。网络板使用一些JSON或XML响应请求,这些JSON或XML表示连接到其上的传感器的状态。node应用程序的想法是记录传感器的变化,然后发射这些变化最终将被另一个electron项目消耗

节点应用程序当前分为两个模块:

代理:对arduino web服务器上的不同端点进行http调用:

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请求或将数据发布到其他服务?