http请求正常,但是频繁更改https请求出现SocketTimeoutException

http request normal,but change https request is frequent occur SocketTimeoutException

最近想把http改成https,结果不是很满意,改成https后经常请求超时,体验很差;我目前的解决方案是使用线程池进行okhttp同步请求,对于http请求是正常的。我想要一个解决方案,谢谢!

第一步:初始化okhttpclient

 public static class MyHttpUtils{
    private static  MyHttpUtils myHttpUtils;

    private OkHttpClient okHttpClient;

    private MyHttpUtils(){
        initClient();
    }

    private void initClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.writeTimeout(60_000, TimeUnit.MILLISECONDS);
        builder.connectTimeout(60_000,TimeUnit.MILLISECONDS);
        builder.readTimeout(60_000,TimeUnit.MILLISECONDS);
        HttpsUtils httpsUtils = HttpsUtils.getInstance();

        HttpsUtils.SSLParams sslParams = httpsUtils.getSslSocketFactory();
        builder.sslSocketFactory(sslParams.sSLSocketFactory,sslParams.trustManager)
                .hostnameVerifier(httpsUtils.hostnameVerifier());//check hostname
        okHttpClient = builder.build();
    }


    public static MyHttpUtils getInstance(){
        if(myHttpUtils == null){
            synchronized (MyHttpUtils.class){
                if(myHttpUtils == null){
                    myHttpUtils = new MyHttpUtils();
                }
            }
        }
        return  myHttpUtils;
    }

    public OkHttpClient getOkHttpClient() {
        return okHttpClient;
    }
}

第二步:创建线程池

public static class  ThreadPool{
    private static  ThreadPool threadPool = new ThreadPool();

    private ExecutorService service = new ThreadPoolExecutor(0 /* corePoolSize */,
            Integer.MAX_VALUE /* maximumPoolSize */, 60L /* keepAliveTime */, TimeUnit.SECONDS,
            new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp ConnectionPool", true));

    public static ThreadPool getInstance(){
        return threadPool;
    }

    public void  execute(Runnable runnable){
        service.execute(runnable);
    }
}

第三步:创建Runnable

private Runnable  createRunnable(){
   return new Runnable() {
       @Override
       public void run() {

           try {
               okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder();
               requestBuilder.url(url).tag(this).build();
               okhttp3.Request request = requestBuilder.build();
               okhttp3.Response response = client.newCall(request).execute();
               if(response.code() == 200){
                  synchronized (this){
                      successSum++;
                  }
                   Log.e(MainActivity.class.getSimpleName(),"success="+successSum);
                   Log.e("myResult","result="+response.body().string());
               }else{
                  synchronized (this){
                      failSum++;
                  }
                   Log.e(MainActivity.class.getSimpleName(),"failSum="+failSum+"==code="+response.code());
               }
           } catch (IOException e) {
               client.connectionPool().evictAll();
              synchronized (this){
                  exceptionSum++;
              }
               Log.e(MainActivity.class.getSimpleName(),"exceptionSum="+exceptionSum+"==msg="+ e.toString());
           }
       }
   };
}

第四步:发送请求

@Override
public void onClick(View view) {
    switch (view.getId()){
        case R.id.btn_request:
            successSum = 0;
            failSum = 0;
            exceptionSum = 0;
            int i = 10;
            while (i>0){
                requestSync();
                i--;
            }

            break;
    }
}

方法:requestSync()

private void requestSync(){
    ThreadPool.getInstance().execute(createRunnable());
}

最终结果:发生SocketTimeoutException

我测试时使用了示例数据,请求成功率在60%左右;这样的结果让我的申请很不友好,但是不知道为什么会这样,希望能得到解决方案,谢谢

此问题已解决。因为使用了同步方式请求,ssl会在握手的时候阻塞其他线程连接主机。解决方法是直接把同步模式改成异步模式