V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
David2077
V2EX  ›  Node.js

关于弱网环境下 axios 流式传输的一些问题想请教下大家

  •  
  •   David2077 · 19 天前 · 1572 次点击

    背景:在 node 弱网环境下 axios 流式传输,网络带宽接近 0KB 的时候网络流(可读流)会触发 aborted ,从而使可写流触发 finish ,导致几十 MB 的文件只有几十 KB 。

    版本:node10 、axios0.19.0

    问题:

    1. 关于 aborted 事件,看了 axios 的源码和 stream 源码,里面好像都没有定义 aborted 事件的定义,不知道它是哪来的(相关代码是我参考 gpt 写上的)
    2. 服务端设置的 timeout 为 5 秒,客户端这边未设置 timeout ,因为 axios 中的 timeout 仅适用于响应超时,而不适用于连接超时,所以应该和 timeout 是无关的。我的理解是客户端收到响应成功后,会建立一个关于 node 流的网络连接,这个流会在内存中进行一些系统级的操作,但是这里的流在文件没下载完就关闭了,不知道是为什么,看来还是因为 aborted 事件,这就又回到了第一个问题上

    代码及打印:(删除相关敏感信息)

    const writer = fsx.createWriteStream(file)
    
    axios
      .get(url, {
        responseType: 'stream',
        ...options
      })
      .then((res) => {
        res.data.pipe(writer)
        writer.on('error', (err) => {
          utils.log(`download error`, err)
          reject(err)
        })
        writer.on('finish', (res) => {
          utils.log(`download finish`, res)
          resolve(res)
        })
        writer.on('close', (err) => {
          utils.log(`download close`, err)
        })
        res.data.on('error', (err) => {
          utils.log(`download error2`, err)
        })
        res.data.on('end', (err) => {
          utils.log(`download end`, err)
        })
        res.data.on('aborted', (err) => {
          utils.log(`download aborted`, err)
        })
        res.data.on('close', () => {
          if (res.request.aborted) {
            utils.log('download aborted')
          } else {
            utils.log('download completed')
          }
        })
      })
    
    [info] download aborted undefined
    [info] download end undefined
    [info] download completed
    [info] download finish undefined
    [info] download close undefined
    
    6 条回复    2024-10-07 18:50:27 +08:00
    ntedshen
        1
    ntedshen  
       19 天前   ❤️ 1
    aborted 是 nodejs 的 http 或者 https 报的,看起来是服务器超时。。。
    网太烂以至于传输 0kb 。。。这不就是超时么。。。

    话说虽然我有自己的 curl 库但是网烂的情况下我都宁可套个 exec aria2 。。。
    David2077
        2
    David2077  
    OP
       18 天前
    我上面响应头里返回的 timeout 设置的是 5s ,这里的流的超时也是 5s 么大佬
    sujin190
        3
    sujin190  
       18 天前 via Android   ❤️ 1
    @David2077 看起来像是响应超时 5s ,读超时应该有另外的吧
    David2077
        4
    David2077  
    OP
       18 天前
    @sujin190 读超时指的是可读流么?流应该是没有超时的说法的
    ntedshen
        5
    ntedshen  
       18 天前   ❤️ 1
    @David2077 不是这事情和流没什么关系,axios 只是对几个常用 curl 方法做的二次封装,对于 nodejs 环境就是 http/https ,原生库。。。
    respType 那个 stream 只是数据输出的形式。。。

    然后响应头里哪有超时,这只是一个服务端配置而已,有几秒这自己测着呗。。。。。。
    以及 timeout 这玩意你不配置也会有默认值的。。。
    所以真的。。。要实在差的感人还是建议套个三方软件,自己写的话想搞什么多线程下载断点续传一类的功能都很难处理好。。。
    David2077
        6
    David2077  
    OP
       15 天前
    @ntedshen 有点懂了多谢大佬
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3291 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 11:30 · PVG 19:30 · LAX 04:30 · JFK 07:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.