midwayjs / midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
https://www.midwayjs.org/
MIT License
7.4k stars 576 forks source link

http 调用如何使用 stream #856

Closed yoodu closed 3 years ago

yoodu commented 3 years ago

函数如下,功能是读取云端文件内容压缩后下载

  @Func('account.getlog')
  async getlog() {
    const { name } = this.ctx.query
    const logPath = Path.join(logDir, name + '.log')
    const rs = fs.createReadStream(logPath)
    const gzip = zlib.createGzip()

    this.ctx.set({
      'Content-Type': 'application/octet-stream',
      'Content-Disposition': 'attachment; filename=' + name + '.log.gz',
    })

    rs.pipe(gzip).pipe(this.ctx.response)
  }

执行后报错如下

TypeError: dest.on is not a function
    at Gzip.Readable.pipe (_stream_readable.js:670:8)
    at AccountService.<anonymous> (/Users/fwk/Documents/_为之/_Electron/_project/account_system/src/index.ts:48:19)
    at Generator.next (<anonymous>)
    at /Users/fwk/Documents/_为之/_Electron/_project/account_system/.faas_debug_tmp/dist/index.js:17:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/fwk/Documents/_为之/_Electron/_project/account_system/.faas_debug_tmp/dist/index.js:13:12)
    at AccountService.getlog (/Users/fwk/Documents/_为之/_Electron/_project/account_system/.faas_debug_tmp/dist/index.js:51:16)
    at FaaSStarter.invokeHandler (/Users/fwk/Documents/_为之/_Electron/_project/account_system/node_modules/@midwayjs/faas/src/starter.ts:205:36)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at FCRuntime.invokeHandlerWrapper (/Users/fwk/.npm-global/lib/node_modules/@midwayjs/faas-cli/node_modules/@midwayjs/runtime-engine/src/lightRuntime.ts:19:22)
czy88840616 commented 3 years ago

函数网关不支持流,只能 return 一个 buffer。

lqsong commented 2 years ago

函数网关不支持流,只能 return 一个 buffer。

请问一下控制器中,不用 ctx.body=stream 与return stream,使用 stream.pipe(this.ctx.res); 怎么设置才可以有效。

czy88840616 commented 2 years ago

函数里在物理架构层面就没法支持,怎么设置都不会成功的。

lqsong commented 2 years ago

函数里在物理架构层面就没法支持,怎么设置都不会成功的。

那midway使用 stream 传输 html,是不是目前无法做到。

czy88840616 commented 2 years ago

在 serverless 场景,无论什么框架都做不到,最终都是变为 buffer 返回。

lqsong commented 2 years ago

在 serverless 场景,无论什么框架都做不到,最终都是变为 buffer 返回。

我可能没有表达清楚,不是在serverless 场景,是正常的 nodejs环境中, midway控制器怎样实现 stream.

lqsong commented 2 years ago

在 serverless 场景,无论什么框架都做不到,最终都是变为 buffer 返回。

不是在serverless 场景,是正常的 nodejs环境中

@Controller('/')
export class HomeController {

  @Get('/')
  async home(): Promise<void> {
    // stream ,不用 ctx.body=stream 与return stream。
   // stream.pipe(this.ctx.res); 页面空白
  }
}

请问怎么实现

czy88840616 commented 2 years ago

不能直接 return stream ?

lqsong commented 2 years ago

不能直接 return stream ?

https://codesandbox.io/s/kind-sammet-j56ro?file=/server/render.js:1448-1474

这个用的 express 结合 react ssr 我想用 midway集成 但是,他的流是输出

const stream = renderToPipeableStream(
    <DataProvider data={data}>
      <App assets={assets} />
    </DataProvider>,
    {
      bootstrapScripts: [assets["main.js"]],
      onShellReady() {
        // If something errored before we started streaming, we set the error code appropriately.
        res.statusCode = didError ? 500 : 200;
        res.setHeader("Content-type", "text/html");
        stream.pipe(res);
      },
      onError(x) {
        didError = true;
        console.error(x);
      }
    }
  );

res是传入的,所以我想midway控制器中是必须 ctx.body=stream 或 return stream 吗。

czy88840616 commented 2 years ago

这不是 midway 的限制,是 koa 的规则。

lqsong commented 2 years ago

这不是 midway 的限制,是 koa 的规则。

那就是说无解,是这个意思吗?

czy88840616 commented 2 years ago

你可以搜索网上 renderToPipeableStream 和 koa2 结合的例子。

lqsong commented 2 years ago

你可以搜索网上 renderToPipeableStream 和 koa2 结合的例子。

在找,所以在这里问下,打扰了。谢谢。

keji commented 1 year ago

前面加上 ctx.respond = false; 不调用框架的reponse而调用node自己的

github-actions[bot] commented 1 year ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.