简体   繁体   English

在node中,在循环中发布HTTP请求(例如0-10000),将错误抛出为:套接字挂起

[英]In node , posting HTTP request in loop (say 0 - 10000), Throws error as: Socket hang up

Code motto: To check the redis pub/sub performance, I am trying to make http request in loop in node.js. 代码座右铭:为了检查redis的发布/订阅性能,我试图在node.js中循环发出http请求。

Problem is :Say my loop ranges from 0 to 10000,when I run the node, it will send post request in loop. 问题是 :说我的循环范围是0到10000,当我运行节点时,它将循环发送发布请求。 It works fine till 120 seconds as expected. 它可以正常工作到120秒,如预期的那样。 After that node throws error as Socket hang up. 在该节点抛出错误后,Socket挂断。 When checking for the solution,I found that the node has default socket timeout as 2 minutes. 在检查解决方案时,我发现该节点的默认套接字超时为2分钟。

Questions are : 1. Will the issue will be solved by changing the default timeout? 问题是 :1.是否可以通过更改默认超时来解决此问题? 2. If so how can we change the default value.? 2.如果是,我们如何更改默认值? 3. Is there any other way can be used to solve this issues other than changing socket timeout value? 3.除了更改套接字超时值,还有其他方法可以用来解决此问题吗?

Code is : 代码是

var clientNo = 100000,a=0;
var express = require('express'),
app = express(),
http = require('http'),
server = http.createServer(app);
http.globalAgent.maxSockets = Infinity;
app.enable('trust proxy'); 
app.disable( 'x-powered-by' ); 
app.use(express.bodyParser());
app.use(app.router);
app.set('port', 6002);

server.listen(app.get('port')); 
var postint= setInterval(function(){
makeSubscription(a,function(query){
var options = {
        path:query,
        port: '6001',
    method: 'POST'
};

var req = http.request(options, function(response){                 
      response.on('end', function () {
          console.log("Ends");
      });
   });
   req.on('error', function (e) {
       console.log(e);          
   });              
       req.end();
    });
a++;
if(a == clientNo)
{
   clearInterval(postint);
}
},1);

Note :I am sending another post request to same port on different path with 1 second setTimeout. 注意 :我正在以1秒setTimeout将另一个发布请求发送到不同路径上的同一端口。

The problem may not strictly be with the timeout, but that the response s are simply sitting idle throughout the duration . 问题可能不完全与超时有关,而是在整个持续时间内response s 只是闲置着

Note that the end event will not fire unless the data is completely consumed. 请注意,除非完全消耗了数据,否则不会触发 end事件。 This can be done by switching into flowing mode, or by calling read() repeatedly until you get to the end. 可以通过切换到流动模式或重复调用read()直到结束来完成此操作。

This is because Streams in Node 0.10 and later don't automatically stream anything . 这是因为Node 0.10及更高版本中的Streams 不会自动流传输任何内容

A Readable stream will not start emitting data until you indicate that you are ready to receive it. 除非您表示已准备好接收数据,否则Readable流将不会开始发射数据。

There are 3 options for getting it to start: 有3个启动它的选项:

  1. Setup flowing mode with 'data' : 使用'data'设置流模式:

     response.on('data', function (chunk) { console.log(data.toString()); }); response.on('end', function () { console.log('End'); }); 
  2. Setup non-flowing mode with 'readable' and .read() : 使用'readable' .read() 'readable'.read()设置非流动模式:

     response.on('readable', function () { var chunk; while (chunk = response.read()) { console.log(chunk.toString()); } }); response.on('end', function () { console.log('End'); }); 
  3. Explicitly tell it to .resume() anyways: 无论如何都明确地将其告知.resume()

     response.resume(); response.on('end', function () { console.log('End'); }); 

Are you sending a valid response from server? 您是否从服务器发送了有效的回复? The error "socket hangup" looks like a timeout waiting for response. 错误“套接字挂起”看起来像是等待响应的超时。 Please check your server code or try to post from rest client like Postman and ensure that you are getting a response. 请检查您的服务器代码,或尝试从诸如Postman之类的其他客户端进行发布,并确保获得响应。

The code can be written simple to do the same job. 可以编写简单的代码来完成相同的工作。

var a=0,clientNo = 10;
var http=require('http');
var sub = setInterval(function(){
  var temp = '/?channel=channel'+a;
  var options = {
  host:'127.0.0.1',
  port:'6001',
  path:temp,
  method:'POST'
  };
  a++;
  var req = http.request(options,function(res){
  res.on('data', function(chunk) {
           console.log('data');
  });
  res.on('error', function(err) {
        console.log(err);
  });
  res.on('end', function() {
       console.log('end');
  });
 });
 req.on('error',function(err){
    console.log(Date());
 });
 req.end();
 if(a== clientNo)
 {
    clearInterval(sub);
 }
},1);

Can send more requests too in same way. 同样可以发送更多请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM