Why is fs.createReadStream … pipe(res) locking the read file?

谁都会走 提交于 2019-12-05 20:33:11
danludwig

It turned out the solution to this was to read and pipe smaller blocks of data from the file during each request. In my test cases for this, I was streaming a 6MB MP4 video file. Though I was able to reproduce the issue using either firefox or chrome, I debugged using the latter, and found that the client was blocking the stream.

When the page initially loads, there is an element that looks something like this:

<video> <!-- or <audio> -->
    <source src="/path/to/express/request" type="video/mpeg" /> <!-- or audio/mpeg -->
</video> <!-- or </audio> -->

As is documented in the other answer referenced in the OP, chrome will send a request with a range header like so:

Range:bytes=0-

For this request, my function was sending the whole file, and my response looked like this:

Accept-Ranges:bytes
Connection:keep-alive
Content-Length:6070289
Content-Range:bytes 0-6070288/6070289
Content-Type:video/mp4

However, chrome was not reading the whole stream. It was only reading the first 3-4MB, then blocking the connection until a user action caused it to need the rest of the file. This explains why closing either the browser or stopping express caused the files to be unlocked, because it closed the connection from either the browser or the server's end.

My current solution is to only send a maximum of 1MB (the old school 1MB, 1024 * 1024) chunk at a time. The relevant code can be found in an additional answer to the question referenced in the OP.

Set autoClose = true in options. If autoClose = false you have to close it manually in 'end' event.

Refer node doc :- https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!