OkHttp超时时间设置
OkHttp3中设置超时的方法
public WebApi(){client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS).build();}
捕获OkHttp3超时
然后捕获异常,加以处理。
public void GetServersList(IServersListEvent serversListEvent) {this.serversListEvent = serversListEvent;serversLoadTimes = 0;Request request = new Request.Builder().url(serversListUrl).build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {if(e.getCause().equals(SocketTimeoutException.class) && serversLoadTimes<maxLoadTimes)//如果超时并未超过指定次数,则重新连接{serversLoadTimes++;client.newCall(call.request()).enqueue(this);}else {e.printStackTrace();WebApi.this.serversListEvent.getServers(null);}}@Overridepublic void onResponse(Call call, Response response) throws IOException {String html = new String(response.body().bytes(), "big5");Matcher m = serversListPattern.matcher(html);ServersList serverList = new ServersList();while (m.find()){serverList.add(new ServerInfo(m.group(1), m.group(2)));}Matcher mc1 = selectServerCodePattern.matcher(html);Matcher mc2 = selectCityCodePattern.matcher(html);if(mc1.find())serverList.selectServerCode=mc1.group(1);if(mc2.find())serverList.selectCityCode=mc2.group(1);WebApi.this.serversListEvent.getServers(serverList);}});}
解析dns超时时间
问题
使用OkHttp,设备切换路由后,访问网络出现长时间无响应,很久以后才抛出UnknownHostException,这明显不是我们想要的,我们设置的connectTimeout属性似乎对dns的解析不起作用。
如何解决
我们先看看OkHttpClient有没有关于Dns的相关设置,发现OkHttpClient的Builder类存在dns()方法可以设置一个Dns类型参数。
Dns类源码如下:
package okhttp3;import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;/*** A domain name service that resolves IP addresses for host names. Most applications will use the* {@linkplain #SYSTEM system DNS service}, which is the default. Some applications may provide* their own implementation to use a different DNS server, to prefer IPv6 addresses, to prefer IPv4* addresses, or to force a specific known IP address.** <p>Implementations of this interface must be safe for concurrent use.*/
public interface Dns {/*** A DNS that uses {@link InetAddress#getAllByName} to ask the underlying operating system to* lookup IP addresses. Most custom {@link Dns} implementations should delegate to this instance.*/Dns SYSTEM = new Dns() {@Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {if (hostname == null) throw new UnknownHostException("hostname == null");try {return Arrays.asList(InetAddress.getAllByName(hostname));} catch (NullPointerException e) {UnknownHostException unknownHostException =new UnknownHostException("Broken system behaviour for dns lookup of " + hostname);unknownHostException.initCause(e);throw unknownHostException;}}};/*** Returns the IP addresses of {@code hostname}, in the order they will be attempted by OkHttp. If* a connection to an address fails, OkHttp will retry the connection with the next address until* either a connection is made, the set of IP addresses is exhausted, or a limit is exceeded.*/List<InetAddress> lookup(String hostname) throws UnknownHostException;
}
这是一个抽象类,并且其中已经写好了默认实现并赋值给了SYSTEM对象。
透过代码我们可以看出,解析dns主要是靠这行代码:
InetAddress.getAllByName(hostname)
Ok,我们已经知道如何解析dns并设置给OkHttpClient了,现在我们只需要重新实现这个过程,插入超时控制,并让OKHttp调用新的Dns解析就好了。
实现
实现抽象类Dns
package com.x.http;import okhttp3.Dns;import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;public class XDns implements Dns {private long timeout;public XDns(long timeout) {this.timeout = timeout;}@Overridepublic List<InetAddress> lookup(final String hostname) throws UnknownHostException {if (hostname == null) {throw new UnknownHostException("hostname == null");} else {try {FutureTask<List<InetAddress>> task = new FutureTask<>(new Callable<List<InetAddress>>() {@Overridepublic List<InetAddress> call() throws Exception {return Arrays.asList(InetAddress.getAllByName(hostname));}});new Thread(task).start();return task.get(timeout, TimeUnit.MILLISECONDS);} catch (Exception var4) {UnknownHostException unknownHostException =new UnknownHostException("Broken system behaviour for dns lookup of " + hostname);unknownHostException.initCause(var4);throw unknownHostException;}}}
}
上面的实现主要依赖了FutureTask可以设置任务执行时间的特性,不明白的同学可以自行学习一下。
然后把新的dns解析类设置给OkHttpClient
public static OkHttpClient createClient(long timeout, long writeTimeout,long readTimeout, boolean bRetry) {OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(timeout, TimeUnit.MILLISECONDS).dns(new XDns(timeout)).retryOnConnectionFailure(bRetry);if (writeTimeout > 0)builder.writeTimeout(writeTimeout, TimeUnit.MILLISECONDS);if (readTimeout > 0)builder.readTimeout(readTimeout, TimeUnit.MILLISECONDS);OkHttpClient client = builder.build();client.dispatcher().setMaxRequestsPerHost(10);client.dispatcher().setMaxRequests(30);return client;}
---------------------
作者:猿小二
来源:CSDN
原文:https://blog.csdn.net/quwei3930921/article/details/85336552
版权声明:本文为博主原创文章,转载请附上博文链接!
new Thread(task).start();
这个地方应该改用线程池,DNS解析应该是比较频繁的操作,直接开新线程不合适
OkHttp超时时间设置相关推荐
- 聊聊ribbon的超时时间设置
序 本文主要研究一下ribbon的超时时间设置 配置 实例 ribbon:ReadTimeout: 10000ConnectTimeout: 10000MaxAutoRetries: 0MaxAuto ...
- Socket超时时间设置
你知道在 Java 中怎么对 Socket 设置超时时间吗?他们的区别是什么?想一想和女朋友打电话的场景就知道了,如果实在想不到,那我们就一起来来看一下是咋回事吧 设置方式 主要有以下两种方式,我们来 ...
- Modbus 超时时间设置
原文链接:https://blog.csdn.net/sunxboy/java/article/details/84499791 Modbus通讯时,需要连续读取多个现场设备的数据,虽然也编写了Mod ...
- 修改服务器超时时间,服务器超时时间设置
服务器超时时间设置 内容精选 换一换 在压测过程中能够提供自身性能数据的施压目标机器.管理执行机的节点.CPTS为用户的测试工程提供管理能力,事务.压测任务.测试报告的内容在同一个测试工程内共享复用, ...
- TCP 超时时间设置过长或 MTU 设置不合理会导致网络速度变慢吗
是的,TCP 超时时间设置过长或 MTU 设置不合理都可能导致网络速度变慢. TCP 超时时间是指在发送数据之后,如果没有收到对端的应答,就会在超时时间后再次发送数据.如果超时时间设置过长,会导致发送 ...
- 联众服务器超时中断,http连接中客户端中断了请求,服务端会中断执行吗?超时时间设置?...
由于http是基于tcp的,在tcp中,客户端中断了连接,服务端是无法感知的,只能通过发心跳包来检测,而显然我们的nginx是没有发心跳包的,所以,包括nginx,php-fpm都是不知道客户端已断开 ...
- 服务器时间修改连接超时时间,服务器设置网络连接超时时间设置
服务器设置网络连接超时时间设置 内容精选 换一换 有以下几种现象:将制作好的SD卡插入开发者板并上电后,开发者板LED1与LED2灯状态信息异常.将制作好的SD卡插入开发者板,并通过USB方式连接Ub ...
- Feign Client的各种超时时间设置
在Spring Cloud微服务架构中,大部分公司都是利用Open Feign进行服务间的调用,而比较简单的业务使用默认配置是不会有多大问题的,但是如果是业务比较复杂,服务要进行比较繁杂的业务计算,那 ...
- httpClient 超时时间设置
上周乐视网cms香港接口,数据刷新缓慢.香港运营人员一直在群里反馈tv端内容不更新. 我观察了下服务器,发现请求接口耗时很久500-6000ms.之前一般都是100ms左右. 导致很多线程一直在wai ...
最新文章
- 代码详解 | 用Pytorch训练快速神经网络的9个技巧
- R语言使用download.file函数下载网络文件到本地(Download File from the Internet)
- 有多少智能,就有多少人工?人工智能背后的数据标注师
- python写入csv文件中文乱码解决方案
- 【Cocos2dx开发】精灵
- Android长度单位详解(dp、sp、px、in、pt、mm、dip)
- 数学--数论--HDU - 6322 打表找规律
- 同步监视器之同步代码块、同步方法
- 《Python自动化》学习笔记:百度云智能实现提取身份证信息
- java中switch、while、do...while、for
- STM32多个串口重定义
- 数据处理可视化的最有价值的 50 张图 (上)
- Compose的手势(六)
- 摄影构图学83年绝版_常用的摄影构图之点线面
- 探讨手机越狱和安装deb文件的几种方式研究
- jenkins如何清缓存,jenkins在结账前清除存储库并强制克隆与清理
- [llvm]查看O3使用了哪些pass
- 不可不看:管理定理一网打尽
- 设备加密有什么作用?
- 3.Maven 常用命令