为什么multipart不生成关闭事件 [英] Why multipart is not generating close events

查看:146
本文介绍了为什么multipart不生成关闭事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我不会处理自己的上传流,而不触摸磁盘驱动器。
所以,我的自然选择是多方模块。



我采用一般的例子,根据 https://npmjs.org/package/multiparty 我将form.parse改为非回调请求。在这种情况下,磁盘将不会被触摸。



我的代码如下所示:

  multiparty = require multiparty)
http = require(http)
util = require(util)

#显示文件上传表单
http.createServer req,res) - >
如果req.url是/ upload并且req.method是POST
form = new multiparty.Form()

form。 on'error',(err) - >
console.log收到错误#{err}

form.on'aborted', - >
console。 logAborted

form.on'part',(part) - >
console.logPart

form.on'close' (part) - >
console.logclose received
res.writeHead 200,
content-type:text / plain
res.endreceived上传:\\\
\\\


form.on'progress',(bytesReceived,bytesExpected) - >
console.logReceived#{bytesReceived},#{bytesExpected}

form.parse req
else
res.writeHead 200,
content-type:text / html

res.end< form action = \/ upload\enctype = \multipart / form-data\method = \post\>+< input type = \\text\name = \title\>< br>+< input type = \file\name = \upload\multiple = \ multiple\>< br>+< input type = \submit\value = \Upload\>+< / form>
) .listen 8080

控制台输出如下所示:

 零件
零件
已接收64983,337353
已接收130519,337353
已中止
收到错误错误:请求已中止

不生成关闭事件,所以我不知道什么时候读取套接字。
如果我更改行:

  form.parse req 

到:

  form.parse req, ,fields,files) - > 
res.writeHead 200,
content-type:text / plain

res.writereceived upload:\\\
\\\

res.end util.inspect(
fields:fields
file:files

然后一切都很好,关闭事件被调用。但是文件存储在磁盘上。控制台如下所示:

 零件
零件
收到65536,337353
收到131072 ,337353
收到196608,337353
收到262144,337353
收到327680,337353
收到337353,337353
收到



任何想法有什么问题?

解决方案

这种情况下,由于你不是管道数据到文件, close 只有当所有数据已经​​从 req 对象,导致 req 在内部发出完成事件,触发多方 close 事件。



在实践中,如果您需要关闭事件,无论是黑洞还是有意义的位置(文件或临时存储流)。这也意味着使用关闭事件继续是非常棘手的控制流程。



如果你不想对数据做任何事情,你可以这样黑洞:

  form.on(part,function(part){
out = new stream.Writable(); // require(stream)to get this native class
out._write = function(chunk,encoding,done){
done(); //不要对数据做任何事情
};
part.pipe );
});

令人困惑的部分是不能访问 c $ c>会为小文件调用 close 事件,但不能在大文件上调用(我遇到了这个问题)。这是因为 close 事件不是绑定到你是否从部分读取数据,而是是否所有数据都已传输出 req



节点流每次只在其缓冲区之间传输几个块。因此,小文件能够将其整个缓冲区从 req 转移到部分,而不填充部分的内部缓冲区。较大的文件将填充部分的缓冲区,但仍然有在 req 中剩余的数据, 部分,以获取 req 缓冲区中剩余的数据。



这个事实也使得使用 close 事件来处理关于控制流的任何事情都很棘手。例如,部分仍然可以处理,但会发送 close ,因为关闭不依赖于部分完成,而是依赖于 req 为空。困惑!


Hi I won't to handle upload stream by myself without touching a disk drive. So, the natural selection for me was multiparty module.

I took the general example and according the instruction from page https://npmjs.org/package/multiparty I changed form.parse to non callback request. In that case the disk won't be touched.

My code looks like this:

multiparty = require("multiparty")
http = require("http")
util = require("util")

# show a file upload form
http.createServer((req, res) ->
  if req.url is "/upload" and req.method is "POST"
    form = new multiparty.Form()

    form.on 'error', (err) ->
      console.log "Error received #{err}"

    form.on 'aborted',  ->
      console.log "Aborted"

    form.on 'part', (part) ->
      console.log "Part"

    form.on 'close', (part) ->
      console.log "close received"
      res.writeHead 200,
        "content-type": "text/plain"
      res.end "received upload:\n\n"

    form.on 'progress', (bytesReceived, bytesExpected) ->
      console.log "Received #{bytesReceived}, #{bytesExpected}"

    form.parse req
  else
    res.writeHead 200,
      "content-type": "text/html"

    res.end "<form action=\"/upload\" enctype=\"multipart/form-data\" method=\"post\">" + "<input type=\"text\" name=\"title\"><br>" + "<input type=\"file\" name=\"upload\" multiple=\"multiple\"><br>" + "<input type=\"submit\" value=\"Upload\">" + "</form>"
).listen 8080 

the console output looks like this:

Part
Part
Received 64983, 337353
Received 130519, 337353
Aborted
Error received Error: Request aborted

The close event is not generated so I don't know when the end of reading the socket. If I change the line:

form.parse req

to:

form.parse req, (err, fields, files) ->
  res.writeHead 200,
    "content-type": "text/plain"

  res.write "received upload:\n\n"
  res.end util.inspect(
    fields: fields
    files: files
  )

Then everything is fine and the close event is called. But the file is stored on the disk. The console looks like this:

Part
Part
Received 65536, 337353
Received 131072, 337353
Received 196608, 337353
Received 262144, 337353
Received 327680, 337353
Received 337353, 337353
close received

Any idea what's wrong?

解决方案

In this case, since you are not piping the data to a file, close is emitted only when all data has been piped out of the req object, causing req to internally emit it's finish event, which triggers the multiparty close event.

In practice, if you need the close event, always pull the data out of the part, whether it is to a blackhole or a meaningful location (file or temporary holding stream). This also means it can be very tricky to use the close event for continuing control flow.

If you don't want to do anything with the data you can blackhole it like so:

form.on("part", function(part) {
    out = new stream.Writable(); // require("stream") to get this native class
    out._write = function (chunk, encoding, done) {
        done(); // Don't do anything with the data
    };
    part.pipe(out);
});

The confusing part is that code which does not access the part will call the close event for small files, but not be called on large files (how I ran into this issue). The reason for that is that the close event isn't bound to whether you have read the data from the part but whether all data has been transferred out of the req.

Node streams only transmit a few chunks at a time between their buffers. Thus, small files are able to transfer their entire buffer from req to part without filling part's internal buffer. Larger files will fill the buffer of the part but still have data left over in the req, requiring a read on the part to get the data remaining in the req buffer.

This fact also makes it tricky to use the close event for anything regarding control flow. In example, a part can still be processing, but close will be sent, again because close isn't dependent on part completion, but rather on req being empty. Confusing!

这篇关于为什么multipart不生成关闭事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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