I was recently trying to change http to https, but the result wasn't so happier because of the frequent request timeouts after changing to https, which made me have a very bad user experience; my current solution is Use a thread pool to perform okhttp synchronization requests, which are normal for http requests. I want a solution, thank you!
first step: init 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;
}
}
Second step: create thread pool
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);
}
}
Third step: create 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());
}
}
};
}
the fourth step:send request
@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;
}
}
Method: requestSync()
private void requestSync(){
ThreadPool.getInstance().execute(createRunnable());
}
final result: occur SocketTimeoutException
I used sample data when testing, and the request success rate is about 60%; this result makes my application very unfriendly, but I'm not sure why this is so, I hope to get a solution, thank you