开发者社区> 问答> 正文

java的okhttp3库中,客户端如何开启http2协议支持 报错

"

题目描述

我在实现向苹果的APNs进行推送的工作,因为APNs需要http2协议,所以我在代码中使用了okhttp3这个库来提供客户端的http2支持。okhttp3是3.14.0版本。
但当我使用

response = client.newCall(request).execute() 

这个同步方法向APNs发送POST数据时,遇到了 java.io.IOException: unexpected end of stream on https://api.development.push....
的异常。

题目来源及自己的思路

我根据在网上搜索的一些方法尝试了不同的参数或配置,但是都没有效果。
经过分析异常初步觉得是APNs返回http2数据,但是客户端默认使用的还是HTTP1.1,导致库读取reponse时用的还是HTTP1.1的相关类和方法,按HTTP1.1的格式去读取HeaderLine而引发了异常。

我尝试的一些配置代码如下:
1.配置H2协议

OkHttpClient.Builder builder = new OkHttpClient.Builder();
List<Protocol> protocols = new ArrayList<>();
// protocols.add(Protocol.H2_PRIOR_KNOWLEDGE);
protocols.add(Protocol.HTTP_2);
protocols.add(Protocol.HTTP_1_1);
builder.protocols(protocols);

2.开启连接重试

builder.retryOnConnectionFailure(true); 

3.配置协议升级的头字段

Request.Builder rb = new Request.Builder();
rb.addHeader("Connection", "Upgrade, HTTP2-Settings").addHeader("Upgrade", "h2c");

4.减小连接keepalive时间

builder.connectionPool(new ConnectionPool(10, 30, TimeUnit.SECONDS));

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)
下面是异常信息:

java.io.IOException: unexpected end of stream on https://api.development.push.apple.com/...
NotificationResponse{error=null, httpStatusCode=-1, responseBody='null', cause=java.io.IOException: unexpected end of stream on https://api.development.push.apple.com/...}
at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.java:233)
at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.java:115)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:43)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:221)
at okhttp3.RealCall.execute(RealCall.java:81)
at com.clevertap.apns.clients.SyncOkHttpApnsClient.push(SyncOkHttpApnsClient.java:338)
at com.clevertap.apns.ClientDemo.req_apns(ClientDemo.java:164)
at com.clevertap.apns.ClientDemo.main(ClientDemo.java:185)
Caused by: java.io.EOFException: \n not found: limit=159 content=0000180400000000000001000010000003000003e8000500004000000600001f…
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:240)
at okhttp3.internal.http1.Http1ExchangeCodec.readHeaderLine(Http1ExchangeCodec.java:238)
at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.java:213)
... 19 more


你期待的结果是什么?实际看到的错误信息又是什么?

请问OKHTTP中如何开启对HTTP2的支持?或者请问我这个异常的真实原因是什么,又如何解决呢?
请不吝指点,非常感谢。

" ![image.png](https://ucc.alicdn.com/pic/developer-ecology/77534df1da1047a096c8b07b3533d08d.png)

展开
收起
因为相信,所以看见。 2020-05-25 15:57:41 2311 0
1 条回答
写回答
取消 提交回答
  • 阿里,我所有的向往

    你好,我也碰到这个相同的问题,请问你最终是什么处理的?谢谢

    ![image.png](https://ucc.alicdn.com/pic/developer-ecology/7d7427cf91fa4d5ca786daaf5ddfd305.png)
    2020-05-25 20:44:11
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
如何通过 Serverless 提高 Java 微服务治理效 立即下载
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载