我最近试图将http更改为https,但是由于更改为https后频繁出现请求超时,结果并没有那么高兴,这给我带来了非常糟糕的用户体验。我当前的解决方案是使用线程池执行okhttp同步请求,这对于http请求是正常的。我想要一个解决方案,谢谢!
第一步:初始化okhttpclient
public partial class Form1 : Form
{
public Process P;
public IntPtr WindowHandle;
public Image TargetButton;
public Form1()
{
InitializeComponent();
Init();
}
private void Init()
{
TargetButton = Bitmap.FromFile("Bucket.JPG");
P = Process.Start("C:\\Windows\\System32\\mspaint.exe");
WindowHandle = P.MainWindowHandle;
// now to find that button and click it, I have the button stored as image in TargetButton variable above
}
}
第二步:创建线程池
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;
}
}
第三步:创建Runnable
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);
}
}
第四步:发送请求
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());
}
}
};
}
方法:requestSync()
@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;
}
}
最终结果:发生SocketTimeoutException
我在测试时使用了样本数据,请求成功率约为60%;这个结果使我的应用程序非常不友好,但是我不确定为什么会这样,我希望得到一个解决方案,谢谢
答案 0 :(得分:0)
此问题已解决。因为使用了同步模式请求,所以在发生握手时,ssl将阻止其他线程连接到主机。解决方案是直接将同步模式更改为异步模式。