java.io.IOException:流已重置:多个设备上的 REFUSED_STREAM

Posted

技术标签:

【中文标题】java.io.IOException:流已重置:多个设备上的 REFUSED_STREAM【英文标题】:java.io.IOException: stream was reset: REFUSED_STREAM on several devices 【发布时间】:2017-03-11 19:27:12 【问题描述】:

我在我的 android 应用中使用 Retrofit 1.9。

服务器使用 nginx 的 Django,使用 HTTP 2 的 HTTPS。证书来自 WoSign,SSL 实验室的“A”分数。

我正在 3 台设备上进行测试:

Nexus 4,Android 5.1.1(官方) Nexus 9,Android 7.0(官方) 三星 Galaxy S3,Android 4.4(官方)

在 SGS3 上它工作正常,但在 Nexus 4 和 9 上却出现异常:

java.io.IOException: stream was reset: REFUSED_STREAM
                                                               at com.squareup.okhttp.internal.framed.FramedStream.getResponseHeaders(FramedStream.java:146)
                                                               at com.squareup.okhttp.internal.http.Http2xStream.readResponseHeaders(Http2xStream.java:150)
                                                               at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:737)
                                                               at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:87)
                                                               at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:722)
                                                               at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:576)
                                                               at com.squareup.okhttp.Call.getResponse(Call.java:287)
                                                               at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:243)
                                                               at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:205)
                                                               at com.squareup.okhttp.Call.execute(Call.java:80)
                                                               at retrofit.client.OkClient.execute(OkClient.java:53)
                                                               at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
                                                               at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
                                                               at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
                                                               at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                               at retrofit.Platform$Android$2$1.run(Platform.java:142)
                                                               at java.lang.Thread.run(Thread.java:761)

【问题讨论】:

【参考方案1】:

如果有人仍有问题(2018 年)。

我已经通过更新改造版本解决了这个问题

 implementation 'com.squareup.retrofit2:retrofit:2.4.0'

【讨论】:

【参考方案2】:

我已经解决了这个问题。这是一个 Nginx bug

此问题已在 Nginx 1.11 中修复。所以,解决方案就是更新到 NGINX 1.11(目前是主线)。

【讨论】:

【参考方案3】:

在我的例子中,nginx 已经更新到 1.11.x。我的罪魁祸首是 okhttp 和改造。当我尝试发出 PUT 请求时,它会以stream was reset: REFUSED_STREAM 失败。

为了解决这个问题,我升级到了两者的最新版本,在我写这篇文章的时候是:

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.5.0'

如果您使用的是 Retrofit 2.0.x 或 okhttp 3.1.x,升级应该可以解决问题。

【讨论】:

以上是关于java.io.IOException:流已重置:多个设备上的 REFUSED_STREAM的主要内容,如果未能解决你的问题,请参考以下文章

saveAsTextFile 在 spark java.io.IOException 中挂起:数据框中的对等方重置连接

OkHttp Android 流已重置:HTTP_1_1_REQUIRED

解决Caused by: java.io.IOException: java.io.IOException: error=12, Cannot allocate memory

Firebase 存储配额在免费计划中重置的天数

React Native:错误:[消息/未知] java.io.IOException:java.util.concurrent.ExecutionException:java.io.IOExcept

java.io.IOException: toDerInputStream 拒绝标签类型 77