提问者:小点点

HTTP/2与OkHttp3和Retrofit 2


我花了很多时间在OkHttp3上做HTTP/2支持来工作,我的想法用完了。

在access. log中检查哪个协议使用连接到服务器的客户端:浏览器:"GET /favicon.icoHTTP/2.0"200 382https://server.com"Mozilla/5.0(X11;Linuxx86_64)"Android客户端:'GET /api/v2/…HTTP/1.1"200 3717" - "" Android…"

服务器与nginx/1.10.2和httpsJAVA_VERSION="1.8.0_76"Android版本="6.0.1"

build. gradle

compile 'com.facebook.stetho:stetho-okhttp3:1.4.2'
compile 'com.squareup.okhttp3:okhttp:3.5.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
...
 client = configureClient(new OkHttpClient().newBuilder())
          .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
          .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
          .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
          .protocols(Arrays.asList(Protocol.HTTP_2, Protocol.SPDY_3, Protocol.HTTP_1_1))
          .addInterceptor(new Interceptor() {
              @Override
              public Response intercept(Chain chain) throws IOException {
                ...
              }
          })
          .addNetworkInterceptor(new StethoInterceptor())
          .build();

我发现我需要将Jetty ALPNjar添加到我的bootclasspath中。所以我刚刚在build. gradle(Project)中添加了以下行:

allprojects {
  ...
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
          options.compilerArgs.add('-Xbootclasspath/p:/home/USER_NAME/Android/alpn-boot/alpn-boot-8.1.2.v20141202.jar')
        }
}

我尝试了所有的alpn启动版本:https://mvnrepository.com/artifact/org.mortbay.jetty.alpn/alpn-boot但没有,甚至错误。

我还试图在build. gradlecompile("org.monbay.jetty.alpn:alpn-boot:VERSION_NUMBER")中添加,但版本7*仍然没有错误并且不起作用。在版本8*中,我在构建应用程序时遇到了以下错误:

Error:Error converting bytecode to dex:
Cause: Dex cannot parse version 52 byte code.
This is caused by library dependencies that have been compiled using Java 8 or above.
If you are using the 'java' gradle plugin in a library submodule add 
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
to that submodule's build.gradle file.

添加目标兼容性='1.7'与源兼容性='1.7'仍然没有。

提前感谢您的任何帮助


共1个答案

匿名用户

Alpn-boot仅用于标准(桌面/服务器)JVM。它不适用于Android设备。

在这种情况下,对bootclasspath的更改也是运行时选项,而不是编译器参数。

AFAIK它应该在Android上自动为https请求工作。

我也看到了同样的事情,一个基于okhttp的测试客户端,得到超文本传输协议/1.1为您的网站,但超文本传输协议/2为twitter。

$ oksocial --debug -i https://api.twitter.com/robots.txt 2>&1  | grep protocol
11:30:28.849    protocol: h2

$ oksocial --debug -i https://debug.api.heyyka.com/api/v1/dev/err 2>&1 | grep protocol
11:30:45.381    protocol: http/1.1

我认为在你的情况下,你依赖NPN而不是ALPN,okhttp不支持。

$ nghttp -v https://debug.api.heyyka.com/api/v1/dev/err
[  0.189] Connected
[  0.362][NPN] server offers:
          * h2
          * http/1.1
The negotiated protocol: h2