我正在尝试创建一个微服务,在收到请求时将数据流式传输到另一个核心服务。
最初,为了处理大型 JSON 负载,我使用了以下内容:
@Get('/zzz/stream')
async streamTiles(
@Param('filterId', new ParseIntPipe()) filterId: number,
@Query() query: Record<string, string> = {},
@Res() res: Response
) {
//... omitted, stream is mongo data stream
await new Promise((resolve, reject) => {
stream
.pipe(JSONStream.stringify())
.pipe(res)
.on('finish', resolve)
.on('error', reject);
});
此解决方案有效,但其效果并不理想。它返回 100 行非常大的 JSON 对象。
我想从客户端进行流式传输,以保持请求的敏捷性和响应速度。
但是,当尝试以下代码时:
@Get('/zzz/stream')
async streamTiles(
@Param('filterId', new ParseIntPipe()) filterId: number,
@Query() query: Record<string, string> = {},
@Res({ passthrough: true }) res: Response
) {
//... omitted, stream is mongo data stream
res.setHeader('Content-Type', 'application/json');
res.setHeader('Transfer-Encoding', 'chunked');
res.setHeader('X-Content-Type-Options', 'nosniff');
stream.pipe(res);
我收到以下回复:
curl: (56) Recv failure: Connection reset by peer
该流实际上是来自游标的 MongoDB 数据流,并且可以确认它是有效的流。
如何纠正这个问题:curl 的响应显示为空?
错误意味着 NestJS 已帮助您强制关闭连接,因此
curl
告诉您连接已关闭。
在您的情况下,
@Res
响应装饰器不应将值设置为{ passthrough: true }
。当 passthrough
设置为 true
时,NextJS 将在函数/处理程序调用完成后自动为您处理请求。
您可以删除
{ passthrough: true }
,以便您可以完全控制响应,并且它应该按预期工作。