将文件流式传输到客户端后,再也不会发送res.end() [英] res.end() is never sent after streaming a file to client

查看:164
本文介绍了将文件流式传输到客户端后,再也不会发送res.end()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上是想将文件从MongoDb流传输到客户端.毫无问题地接收到文件,但是当流结束并且我尝试发送request.end()时,客户端永远不会收到它.

I'm basically trying to stream a file from a MongoDb to a client. The file is received with no problem, but when the stream ends and i try to send a request.end() the client never get it.

app.post('/upload', function (req, res) {
    var db = new mongo.Db('prueba', new mongo.Server("127.0.0.1", 27017));
    db.open(function (err) {
        if (err) return handleError(err);

        var gfs = Grid(db, mongo);
        console.log(req.filename);
        var uploadedSize = 0,
            uploadProgress = 0;
        idPdf = new ObjectId();  //cliente crea un id de mongo, el cual se utilizara para traer el recurso despues
        console.log(idPdf);

        var grabarm = req.pipe(gfs.createWriteStream({
            filename: 'test',
            _id: idPdf
        }));

        grabarm.on("close", function () {

            var tbuffer = gfs.createReadStream({filename: 'test'});

            tbuffer.on('open', function () {
                // This just pipes the read stream to the response object (which goes to the client)
                res.setHeader('Content-disposition', 'attachment; filename=pdfmongo.pdf');
                res.setHeader('Content-type', 'application/pdf');

                tbuffer.pipe(res);
            });

            tbuffer.on('data', function (chunk) {
                console.log("receiving data");
            });
            tbuffer.on("close", function () {

                console.log("fin"); //can see it in console
                res.end("ok file received");//client never sees this

            });

            tbuffer.on('error', function (err) {
                res.end(err);
            });
        });

    });

});

推荐答案

当您的可读流完成读取时,默认情况下,它发出并发送end()事件,该事件将在可写流上调用end()事件(res溪流).在这种情况下,您不必担心调用end().

When your readable stream finishes reading, by default, it emits and end() event, which will call the end() event on the writable stream (the res stream). You don't need to worry about calling end() in this case.

因此,在调用end()事件后,您的res将不再可写.因此,如果要使其可写,只需将end:false选项传递给pipe()即可.例如:

So your res will no longer be writable after the end() event is called. So, if you want to keep it writable, just pass the end: false option to pipe(). For an example:

fs.createReadStream("./image.png").pipe(res, { end: false });

,然后稍后再调用end()事件.

, and then call the end() event sometime later.

顺便说一句,您应该侦听结束"事件而不是关闭"事件,因为流完成,因为关闭"并不明确表示所有数据都已传输.

Btw you should listen to 'end' event instead of 'close' event for stream finish cuz 'close' does not explicitly means all data has been transferred.

这篇关于将文件流式传输到客户端后,再也不会发送res.end()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆