javascript - 文件下载和客户端断开连接?

标签 javascript node.js express

给定以下代码:

async function (req, res, next) {
  const fd = await fs.open("myfile.txt")
  fs.createReadStream(null, { fd, autoClose: false })
    .on('error', next)
    .on('end', () => fs.close(fd))
    .pipe(res)
}

如果客户端在下载整个文件之前断开连接会怎样?即 end 是否仍会被调用,或者文件描述符是否已泄漏,如果是,我该如何修复?如果调用“end”是否意味着即使客户端不再监听它也会读取整个文件?

请注意,我知道我可以在没有 fd 的情况下执行此操作,但这是对更复杂代码的简化。

最佳答案

看起来文件不会关闭,或者至少不会调用您的 end 事件处理程序。

您可以为此创建测试,但这是我的:

const http = require('http');
const fs   = require('fs');

var server = http.createServer(function (req, res) {
    console.log('server request received');
    const fd = fs.openSync('myfile.txt', 'r');
    fs.createReadStream(null, { fd, autoClose: false })
        .on('error', err => {
            console.error('file error', err);
        })
        .on('end', () => {
            console.log('file end');
            fs.close(fd);
        })
        .on('close', () => {
            console.log('file closed');
        })
        .pipe(res)
            .on('error', err => console.error('server stream error', err))
            .on('end', () => console.log('server stream end'))
            .on('close', () => console.log('server stream closed'))
    ;
});

server.listen(0, 'localhost', () => {
    const address = server.address();

    var req = http.request({port: address.port}, function (res) {
        res.on('data', data => {
            console.log('response data');
            // Comment next line to read whole file.
            req.abort();
        });
        res.on('end', () => {
            console.log('response ended');
            setTimeout(() => server.close(), 1000);
        });
        req.once('abort', () => {
            console.log('request aborted');
        });
    });

    req.end(() => {
        console.log('request sent');
    });
});

为了简化运行测试,我删除了 async/wait。

req.abort() 被调用时,我得到以下输出:

request sent
server request received
response data
request aborted
response ended
server stream closed

注释该行并允许代码读取整个文件后:

request sent
server request received
response data
response data
response data
response data
response data
response data
file end
response data
response ended

为了创建测试 myfile.txt 我使用了以下命令:

dd if=/dev/zero of=myfile.txt bs=1k count=200

关于javascript - 文件下载和客户端断开连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37508826/

相关文章:

javascript - css 未在 nodejs 网络应用程序中呈现

node.js - Express EJS : "Value Not Defined", 但它在 "If"内部

javascript - 如何在不使用html标签的情况下在angularJS中运行for循环?

javascript - jQuery 下拉列表悬停

javascript - 多个 JavaScript 倒计时日期?

node.js - 如何使用 "cors"库在 Express Route 上配置 CORS

javascript - req.body 返回未定义?

JavaScript 正则表达式接受 00.01 到 999.99999 之间的值

jquery - 使用 jQuery POST 时未保存 NodeJS Express session 变量

node.js - 支持一个或两个或两个命令的 Docker 入口点脚本(即 npm config 和 npm run)