【问题标题】:Problem when uploading video: Stream was reset: NO_ERROR上传视频时出现问题:流已重置:NO_ERROR
【发布时间】:2020-03-16 09:34:54
【问题描述】:

我正在开发一个使用 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)
        }
    })
}

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

com.androidnetworking.error.ANError: okhttp3.internal.http2.StreamResetException: stream was reset: NO_ERROR

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

com.androidnetworking.error.ANError: java.net.SocketTimeoutException: timeout

关于这里可能有什么问题的任何想法?

【问题讨论】:

    标签: android kotlin okhttp fast-android-networking


    【解决方案1】:

    我遇到了同样的问题 - 获取带有错误代码 NO_ERRORRST_STREAM 框架。我试图通过 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();
    

    然后我会得到HTTP 413 Entity Too Large

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

    【讨论】:

    • 对不起,你能解释一下如何将客户端包限制设置为更高的值吗?
    • @SlavaVir,对不起,我对服务器端不是很了解。我只能说我们需要更改 Nginx 配置文件以允许更大的 JSON 包。我希望这个link to Nginx configuration doc可以解释更多。
    【解决方案2】:

    我找到了解决办法:

    MultipartBody.Builder builder = new MultipartBody.Builder();
    builder.setType(MultipartBody.FORM);
    

    仅在构建器多部分主体上设置类型。

    【讨论】:

      【解决方案3】:

      我最终直接使用 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()
                  }
              }
          })
      }
      

      【讨论】:

      • 请分享“newCall”功能。
      • 嗯,这是OkHttpClient 的方法之一。 here 是文档的链接。
      猜你喜欢
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-14
      • 2016-01-20
      相关资源
      最近更新 更多