首页 > 解决方案 > okHttp3保持活动连接不起作用

问题描述

我正在使用 okhttp3 和 retrofit2 来获取 json 文件。我尝试了一切以使用保持活动连接来更快地下载数据,但似乎没有任何效果。

我已经实现了拦截器并添加了 keep-alive 标头。但似乎它只是不想工作。有人可以查看我的代码并告诉我我在这里做错了什么吗?这是我的代码:

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
ConnectionPool connectionPool = new ConnectionPool(3, 10, TimeUnit.MINUTES);
Gson gson = new GsonBuilder()
                .setLenient()
                .create();

        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.connectionPool(connectionPool)
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS);
        httpClient.interceptors().add(logging);
        httpClient.interceptors().add(new Interceptor() {
            @NotNull
            @Override
            public Response intercept(@NotNull Chain chain) throws IOException {
                Request original = chain.request();

                // Customize the request
                Request request = original.newBuilder()
                        .header("Connection", "Keep-Alive")
                        .method(original.method(), original.body())
                        .build();

                try {
                    Response response = chain.proceed(request);
                    if (!response.isSuccessful()) {
                            response.close();
                            connectionPool.evictAll();
                            Log.d("okokok", "evict");
                            return chain.proceed(request);
                        } else {
                            // Customize or return the response
                            Log.d("okokok", "return response");
                            return response;
                        }
                } catch (IOException e) {
                    e.printStackTrace();
                    connectionPool.evictAll();
                    return chain.proceed(request);
                }
            }
        });

        OkHttpClient client = httpClient.build();
        Retrofit retrofit = new Retrofit.Builder()

                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build();

        postService = retrofit.create(PostService.class);

根据此代码,标头应包含 Keep-Alive 并且连接不应关闭至少一分钟。

我还检查了我的服务器,发现它确实接受了 Keep-Alive 标头,并且在 GTMatrix 测试中也表明 Keep-Alive 确实在我的服务器上工作。但由于某种原因,android 应用程序不断关闭连接,每次我加载新文件时,都需要时间与服务器建立新连接。

我尝试使用 Firebase 实时数据库并保存了我的 json 数据。当我从那里查询时,我惊讶地发现数据下载速度与第一次查询的改造完全相同,但在第一次查询之后,每个其他查询都需要几毫秒来加载数据。这意味着比改造快 10 到 20 倍。

我想在这里添加的一件事是,我正在使用 Glide 从服务器加载图像,而 Glide 似乎很好地使用 Keep-Alive 设置安静,因为 Glide 非常有效地加载图像,完全没有延迟。所以这个下载慢的问题似乎只和okhttp3 + Retrofit有关。

谁能调查一下,让我知道我在这里做错了什么?我已经在这个问题上工作了 2 周,但仍然没有找到解决方案。我阅读了与此问题相关的每个 stackoverflow 问题,但似乎没有任何效果。

标签: androidretrofit2okhttp3

解决方案


好吧,这段代码运行良好,我发现我的主机在 keepAliveTimeout 上的限制为 5 秒,这就是 KeepAlive 仅工作 5 秒并且连接关闭后的原因。除非我更改主机,否则无论我做什么代码都无法更改。


推荐阅读