上传视频时出现问题:流已重置:NO_ERROR

Ren*_*oni 6 android kotlin okhttp fast-android-networking

我正在开发一个使用 TUS 方法将视频上传到 Vimeo 的应用程序。

我为 Fast Android Networking 编写了一个简单的包装器,用于上传视频文件的每个部分。

fun patch(
    destination: RequestDestination = RequestDestination.Api,
    url: String,
    headers: Map<String, Any> = mapOf(),
    body: ByteArray? = null,
    contentType: String? = null,
    priority: Priority = Priority.MEDIUM,
    jsonRequest: Boolean = true,
    success: (Any?) -> Unit,
    failure: (ANError?) -> Unit
) {
    val requestUrlString = getFullUrl(destination, url) // Determines the destination URL, is working correctly
    val request = AndroidNetworking.patch(requestUrlString)
    setRequestAttributes(request, headers, destination, priority) // Adds the request params, headers, etc to the request, works correctly
    if (contentType != null) { 
        request.setContentType(contentType) 
    }

    if (body != null) {
        request.addByteBody(body) 
    }

    request.build().getAsOkHttpResponse(object : OkHttpResponseListener {
        override fun onResponse(response: Response?) {
            success(response)
        }

        override fun onError(anError: ANError?) {
            failure(anError)
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

这似乎不一致地失败,有时工作正常,有时则不然。上传的部分大小为 70MB。抛出的错误是:

com.androidnetworking.error.ANError: okhttp3.internal.http2.StreamResetException: stream was reset: NO_ERROR
Run Code Online (Sandbox Code Playgroud)

通常,我通过按照 TUS 指定的方式重试上传来从错误中恢复,但是,在获取资源并重试补丁后,网络活动显着下降(从几 Mbps 到几 Kbps),并最终发生套接字超时:

com.androidnetworking.error.ANError: java.net.SocketTimeoutException: timeout
Run Code Online (Sandbox Code Playgroud)

关于这里可能出什么问题有什么想法吗?

Vla*_*zin 7

我遇到了同样的问题 - 获取RST_STREAM带有错误代码的框架NO_ERROR。我试图通过 HTTP/2 上传相当大的数据块。每当我像这样强制使用 HTTP/1_1 时

List<Protocol> protocols = new ArrayList<Protocol>()
        {{
            add(Protocol.HTTP_1_1); // <-- The only protocol used
            //add(Protocol.HTTP_2); 
        }};
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(20L, TimeUnit.SECONDS)
                .writeTimeout  (20L, TimeUnit.SECONDS)
                .readTimeout   (20L, TimeUnit.SECONDS)
                .protocols(protocols)
                .build();
Run Code Online (Sandbox Code Playgroud)

然后我会得到HTTP 413 Entity Too Large

解决方案是明确告诉代理将客户端包限制设置为更高的值(默认为 1MB)。之后不仅 HTTP/1_1 可以工作,HTTP/2 也可以工作。

  • @SlavaVir,抱歉,我对服务器端不是很了解。我只能说我们需要更改 Nginx 配置文件以允许更大的 JSON 包。我希望 Nginx 配置文档的[链接](https://docs.nginx.com/nginx-app-protect/configuration/) 可以解释更多。 (2认同)

Ren*_*oni 0

我最终直接使用 OkHttp3 将数据上传到 Vimeo。这是我的解决方案:

fun basicPatch(
    url: String,
    headers: Map<String, String> = mapOf(),
    data: ByteArray,
    success: (Response) -> Unit,
    failure: (IOException) -> Unit
) {
    val tusMediaType = MediaType.parse("application/offset+octet-stream")
    val body = RequestBody.create(tusMediaType, data)

    val request = Request.Builder()
        .url(url)
        .headers(Headers.of(headers))
        .patch(body)
        .build()
    client.newCall(request).enqueue(object: Callback {
        override fun onFailure(call: Call, error: IOException) {
            failure(error)
        }

        override fun onResponse(call: Call, response: Response) {
            success(response)
            if (response.isSuccessful) {
                response.close()
            }
        }
    })
}
Run Code Online (Sandbox Code Playgroud)