【问题标题】:keep-alive connection with Superagent与 Superagent 保持连接
【发布时间】:2014-01-11 16:08:12
【问题描述】:

我正在运行一个 node.js 服务器 A,它使用 superagent 向另一台服务器 B 发出 HTTP 请求。

我调查了服务器 B 上的请求,发现标头 connectionclose,httpVersion 是 1.1

var http = require('http');
var request = require('superagent');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('req.httpVersion seen on server:' + req.httpVersion);
  res.write('\nreq.headers.connection seen on server:' + req.headers.connection);
  res.end();
}).listen(1337, '0.0.0.0');

request
  .get('localhost:1337/helloword')
  .end(function (err, res) {
    console.log(res.text);
  });

这导致:

req.httpVersion seen on server:1.1
req.headers.connection seen on server:close

但是,如果我从浏览器访问同一服务器,我会得到:

req.httpVersion seen on server:1.1
req.headers.connection seen on server:keep-alive

https://www.rfc-editor.org/rfc/rfc2616#page-172 我了解到keep-alive 是HTTP 1.1 的默认值,除非使用Connection: close 另有声明。

所以,我的问题是:

  • 为什么 Superagent / Node.js 明确将请求设置为不使用 keep-alive / 持久连接?
  • 如何强制 Superagent / Node.js 使用 keep-alive 连接?
  • 如何进一步影响确切的行为(保持打开的连接数、超时等)?

【问题讨论】:

    标签: node.js http keep-alive superagent


    【解决方案1】:

    似乎没有记录,但您可以使用函数agent 将 http 代理传递给超级代理。 因此,您可以使用此模块创建一个保持活动状态的代理:https://www.npmjs.org/package/agentkeepalive 并将其传递给超级代理。

    类似这样的:

    util = require('util');
    util.debuglog = require('debuglog');
    var http = require('http');
    var request = require('superagent');
    var Agent = require('agentkeepalive');
    
    var keepaliveAgent = new Agent({
      maxSockets: 100,
      maxFreeSockets: 10,
      timeout: 60000,
      keepAliveTimeout: 30000 // free socket keepalive for 30 seconds
    });
    
    http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.write('req.httpVersion seen on server:' + req.httpVersion);
      res.write('\nreq.headers.connection seen on server:' + req.headers.connection);
      res.end();
    }).listen(1337, '0.0.0.0');
    
    request
      .get('localhost:1337/helloword')
      .agent(keepaliveAgent)
      .end(function (err, res) {
        console.log(res.text);
      });
    

    【讨论】:

      【解决方案2】:

      浏览器可以重用套接字句柄,因此它将标头Connection: keep-alive发送到服务器。

      如果你想保持连接,你可以像这样发送这个标头:

      request
      .get('localhost:1337/helloword')
      .set('Connection', 'keep-alive')
      .end(function (err, res) {
         console.log(res.text);
      });
      

      【讨论】:

      • 嗯,这真的够吗?接收方“服务器 B”可以并将其作为保活连接处理。但我怀疑在请求方“服务器 A”这是否足够。在我看来,“服务器 A”仍然会在每次发出请求时打开一个新连接。我还不确定如何证明/验证这一点。
      • 我不知道。但是 superagent 依赖于node.js http,并且node.js http 支持keep-alive 以重用套接字。 nodejs.org/api/http.html#http_http_createserver_requestlistener
      • @dknaus 当你这样尝试时会发生什么?结果如何?
      【解决方案3】:

      对于 superagent .timeout(5000) 也可以使用。

                          await superagent.get(`${anyurl}`, { rejectUnauthorized: false })
                              .set({ "Accept": "application/json", "Content-Type": "application/json", })
                              .auth(username, password, { "type": "auto" })
                              .timeout(1000)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-21
        • 1970-01-01
        • 1970-01-01
        • 2015-04-26
        • 2021-12-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多