求助,ctx.body在特定情况下失败
场景: 前端上传一个视频 ==》 服务器A(存在本地,上传到对象存储后删除) ==》 对象存储服务器 ==》 反馈前端 视频地址 故障: 1)当视频较小,在100M之下的时候是正常的,前端能正常收到消息 2)视频大于100M,服务器已经执行到ctx.body,但是前端还在一直等待,无法收到ctx.body发送的消息 伪代码:
// write to local
await wirteToLocal()
// upload
await putObject()
// send to front end
ctx.body = {
video_id: res.fileId,
video_url: res.video.url
}
服务器打印日志
浏览器内network信息
一直等待,实际上已经执行完毕(无法理解的是视频较小的情况下是正常的)
2 回复
虽然不知道什么原因。不过你可以试试 直接 ctx.res.end()
@cd-xulei 试过了,跟ctx.body的表现一致,推测是长时间和前端没有数据交换,keepalive不再刷新时间,socket最终被销毁。
考虑 1、PassThrough定时传输没有实际意义的数据来保持连接; 2、不把文件写到服务器,直接pipe到对象存储服务器。
我最终选择的是直接pipe到对象存储服务器
PassThrough的实现逻辑(伪代码)
const PassThrough = require('stream').PassThrough;
let stream = new PassThrough();
ctx.response.status = 200;
ctx.response.type = 'text/event-stream;charset=utf-8';
ctx.response.set('Cache-Control', 'no-cache');
ctx.body = stream;
//保持连接
settimeout递归/setIntervel ==> stream.write(`working`);
//结束
clearTimeout
ctx.res.end(JSON.stringify({fileId,video_url}))