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会在握手的时候阻塞其他线程连接主机。解决方法是直接把同步模式改成异步模式
最近想把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会在握手的时候阻塞其他线程连接主机。解决方法是直接把同步模式改成异步模式