在 node.js 中使用 node-fetch 重用 TCP 连接

Posted

技术标签:

【中文标题】在 node.js 中使用 node-fetch 重用 TCP 连接【英文标题】:Reuse TCP connection with node-fetch in node.js 【发布时间】:2020-10-11 11:07:44 【问题描述】:

我正在使用此函数调用外部 API

const fetch = require('node-fetch');

fetchdata= async function (result = ) 
  var start_time = new Date().getTime();

    let response = await fetch('API endpoint', 
      method: 'post',
      body: JSON.stringify(result),
      headers:  'Content-Type': 'application/json' ,
      keepalive: true

    );

  console.log(response) 
  var time =  'Respone time': + (new Date().getTime() - start_time) + 'ms' ;
  console.log(time)
  return [response.json(), time];
  

问题是我不确定每次我使用这个函数时 node.js 是否重用了到 API 的 TCP 连接,即使我定义了 keepalive 属性。

重用 TCP 连接可以显着提高响应时间 欢迎提出任何建议。

【问题讨论】:

【参考方案1】:

这是一个基于其文档的 node-fetch 包装器:

import nodeFetch,  RequestInfo, RequestInit  from "node-fetch";
import http from "http";
import https from "https";

const httpAgent = new http.Agent(
  keepAlive: true
);

const httpsAgent = new https.Agent(
  keepAlive: true
);

export const fetch = (url: RequestInfo, options: RequestInit = ) => 
  return nodeFetch(url, 
    agent: (parsedURL) => 
      if (parsedURL.protocol === "http:") 
        return httpAgent;
       else 
        return httpsAgent;
      
    ,
    ...options
  );
;

【讨论】:

【参考方案2】:

这里是 node-fetch 的包装器,用于添加 keepAlive 选项,基于 Ilan Frumer 的回答

// fetch: add option keepAlive with default true
const fetch = (function getFetchWithKeepAlive() 
  const node_fetch = require('node-fetch');
  const http = require('http');
  const https = require('https');
  const httpAgent = new http.Agent( keepAlive: true );
  const httpsAgent = new https.Agent( keepAlive: true );
  return async function (url, userOptions) 
    const options =  keepAlive: true ;
    Object.assign(options, userOptions);
    if (options.keepAlive == true)
      options.agent = (parsedUrl => parsedUrl.protocol == 'http:' ? httpAgent : httpsAgent);
    delete options.keepAlive;
    return await node_fetch(url, options);
  
)();

const response = await fetch('https://github.com/');
const response = await fetch('https://github.com/',  keepAlive: false );

【讨论】:

【参考方案3】:

keep-alive 不是 enabled 的默认使用 agent 和 is not currently implemented 直接进入 node-fetch,但您可以轻松地指定 custom-agent 启用 keep-alive 选项:

const keepAliveAgent = new http.Agent(
    keepAlive: true
);

fetch('API endpoint', 
     ...
     agent: keepAliveAgent         
);

【讨论】:

【参考方案4】:

如 https://github.com/node-fetch/node-fetch#custom-agent 中所述

const fetch = require('node-fetch');

const http = require('http');
const https = require('https');

const httpAgent = new http.Agent( keepAlive: true );
const httpsAgent = new https.Agent( keepAlive: true );
const agent = (_parsedURL) => _parsedURL.protocol == 'http:' ? httpAgent : httpsAgent;

const fetchdata = async function (result = ) 
    var start_time = new Date().getTime();

    let response = await fetch('API endpoint', 
        method: 'post',
        body: JSON.stringify(result),
        headers:  'Content-Type': 'application/json' ,
        agent
    );

    console.log(response)
    var time =  'Respone time': + (new Date().getTime() - start_time) + 'ms' ;
    console.log(time)
    return [response.json(), time];


【讨论】:

谢谢大家!这是最有帮助的

以上是关于在 node.js 中使用 node-fetch 重用 TCP 连接的主要内容,如果未能解决你的问题,请参考以下文章

在 node.js 中使用 node-fetch 将数据发送到 Pure Data (Pd) 导致 ETIMEDOUT

node.js node-fetch - 传递附加到url的查询字符串的问题

node-fetch 从 html 网站获取 id 但我收到错误 200 undefined

如何将 *any* cURL 或 node-fetch 请求转换为 Axios 请求?

react服务端渲染路由改写

西塔 js。如何与 Node JS 一起使用