HTTP/2 使用 OkHttp3 和 Retrofit2
HTTP/2 with OkHttp3 and Retrofit2
我花了很多时间来 HTTP/2 对 OkHttp3 的支持,但我 运行 没有想法。
如何检查它是否有效:
检查 access.log 哪个协议使用连接到服务器的客户端:
浏览器:"GET /favicon.ico HTTP/2.0" 200 382 https://server.com "" Mozilla / 5.0 (X11; Linux x86_64)"
Android 客户:'GET /api/v2/ ... HTTP/1.1 "200 3717" - "" Android ..."
我用的是:
带有 nginx/1.10.2
和 https 的服务器
JAVA_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 ALPN jar 添加到我的引导类路径中。
所以我刚刚在 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-boot 的版本:https://mvnrepository.com/artifact/org.mortbay.jetty.alpn/alpn-boot 但什么也没有,甚至是错误消息。
我也尝试在 build.gradle compile("org.mortbay.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.
添加 targetCompatibility = '1.7' 和 sourceCompatibility = '1.7' 仍然没有。
提前感谢您的帮助
alpn-boot 仅用于标准 (Desktop/Server) JVM。它不适用于 Android 设备。
在这种情况下,对 bootclasspath 的更改也是一个运行时选项,而不是编译器参数。
据我所知,对于 https 请求,它应该在 Android 上自动运行。
n.b。我也看到了同样的事情,使用基于 okhttp 的测试客户端,为您的站点获取 http/1.1,但为 twitter 获取 http/2。
$ 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
我花了很多时间来 HTTP/2 对 OkHttp3 的支持,但我 运行 没有想法。
如何检查它是否有效:
检查 access.log 哪个协议使用连接到服务器的客户端:
浏览器:"GET /favicon.ico HTTP/2.0" 200 382 https://server.com "" Mozilla / 5.0 (X11; Linux x86_64)"
Android 客户:'GET /api/v2/ ... HTTP/1.1 "200 3717" - "" Android ..."
我用的是:
带有 nginx/1.10.2
和 https 的服务器
JAVA_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 ALPN jar 添加到我的引导类路径中。 所以我刚刚在 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-boot 的版本:https://mvnrepository.com/artifact/org.mortbay.jetty.alpn/alpn-boot 但什么也没有,甚至是错误消息。
我也尝试在 build.gradle compile("org.mortbay.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.
添加 targetCompatibility = '1.7' 和 sourceCompatibility = '1.7' 仍然没有。
提前感谢您的帮助
alpn-boot 仅用于标准 (Desktop/Server) JVM。它不适用于 Android 设备。
在这种情况下,对 bootclasspath 的更改也是一个运行时选项,而不是编译器参数。
据我所知,对于 https 请求,它应该在 Android 上自动运行。
n.b。我也看到了同样的事情,使用基于 okhttp 的测试客户端,为您的站点获取 http/1.1,但为 twitter 获取 http/2。
$ 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