java - 如何在 VertX 中完成分段上传后关闭连接

标签 java kotlin upload vert.x

我正在 VertX 中构建流式上传,以便可以将上传直接流式传输到 Google Cloud/AWS S3 存储桶,但在浏览器中查看网络选项卡时,上传似乎永远不会结束。
这是我正在使用的测试上传表单:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form>
    <input type="text" value="blah">
    <input multiple type="file">
</form>
<div>

</div>
<script>
    let input = document.querySelector("input[type='file']")
    let div = document.querySelector("div")
    input.addEventListener("change", event => {
        let files = event.target.files
        console.log(files)
        const formData = new FormData()
        for (let file of files) {
            formData.append(file.name, file)
            formData.append("blah", "blah")
        }
        window.fetch("http://localhost:11111/le-upload-test?testing=true", {
            method: "POST",
            body: formData
        }).then(response => {
            div.innerHTML = ""
            div.append(`${response.statusText} - ${response.status}`)
            console.log(response)
        })
    })
</script>
</body>
</html>
在后端,
class MyServer(
    val port: Int,
) : CoroutineVerticle() {

    val log = LoggerFactory.getLogger(this.javaClass)

    init {
        Vertx.vertx()?.deployVerticle(this) 
            ?: throw Exception("Failed to start VertX")
    }

    override suspend fun start() {
        vertx.createHttpServer().requestHandler { req ->
            println(req.path())
        
            if (req.path() == "/le-upload-test") {
                req.isExpectMultipart = true
                req.uploadHandler { upload ->
                    println("==================")
                    println(req.params())
                    println(upload.filename())
                    println("==================")
                    upload.handler { chunk ->
                        println("chunk.length=${chunk.length()}")
                        println("total.read=${req.bytesRead()}")
                    }
                }
            }
        }.listen(port)
    }
}

fun main() {
    MyServer(
        port = 11111,
    )
}
上传多个文件时,这会正确输出:
/le-upload-test
==================
testing=true

Screenshot_20201026_211340.png
==================
chunk.length=239
total.read=422
chunk.length=8192
total.read=8614
chunk.length=8192
...
==================
testing=true

Screenshot_20201026_181456.png
==================
chunk.length=192
total.read=74150
chunk.length=7770
total.read=81920
...
我应该在什么时候调用 req.response.end("...")
除非我重新启动服务器,否则浏览器会无限期地卡在那里?
enter image description here
我试过做:
req.uploadHandler { upload ->
    val contentLength = req.getHeader("Content-Length")
    upload.handler { chunk ->
        if (req.bytesRead().toString() == contentLength) {
            println("DONE!!")
            req.response().setStatusCode(200).end("DONE")
        }
    }
}
处理完所有字节后,这会正确打印 DONE ,但浏览器会显示 failed, EMPTY RESPONSE
upload.endHandler 之后添加 upload.handler
    upload.endHandler {  end ->
        println("DONE!!!")
        req.response().setStatusCode(200).end("TEST")
    }
处理完所有字节后会正确打印 DONE!!! 部分,但也不会关闭状态为 200 的上传连接。

最佳答案

设法让它工作,似乎它所缺少的只是一个 CORS header

    override suspend fun start() {
        vertx.createHttpServer().requestHandler { req ->

            println(req.path())
            try {
                if (req.path() == "/le-upload-test") {

                    req.response().putHeader("Access-Control-Allow-Origin", "*")

                    req.isExpectMultipart = true
                    req.uploadHandler { upload ->
                    req.endHandler {                        
                        req.response().end("BLAH!!")
                        println("DONE")
                    }
enter image description here

关于java - 如何在 VertX 中完成分段上传后关闭连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64576785/

相关文章:

gradle - Gradle无法解析 'kotlin'插件。我是否缺少正确的Maven存储库?

android - Kotlin 自定义对话框参数指定为非空

java - 如何让对象在自己的线程中与其他代码同时运行其命令

java - 使用Index API同步将数千条记录索引到Elasticsearch中是正确的方法吗?

java - Java中的单例模式实现

kotlin - Kotlin 中的对象和数据类有什么区别?

php - 多个文件上传不会将所有文件插入数据库

jQuery、blueimp文件上传: clear form only works onclick

javascript - 如何使用 ajax 和 django 上传文件?

java - 将正确的 xml 转换为不正确的 xml