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超时时间设置相关推荐

  1. 聊聊ribbon的超时时间设置

    序 本文主要研究一下ribbon的超时时间设置 配置 实例 ribbon:ReadTimeout: 10000ConnectTimeout: 10000MaxAutoRetries: 0MaxAuto ...

  2. Socket超时时间设置

    你知道在 Java 中怎么对 Socket 设置超时时间吗?他们的区别是什么?想一想和女朋友打电话的场景就知道了,如果实在想不到,那我们就一起来来看一下是咋回事吧 设置方式 主要有以下两种方式,我们来 ...

  3. Modbus 超时时间设置

    原文链接:https://blog.csdn.net/sunxboy/java/article/details/84499791 Modbus通讯时,需要连续读取多个现场设备的数据,虽然也编写了Mod ...

  4. 修改服务器超时时间,服务器超时时间设置

    服务器超时时间设置 内容精选 换一换 在压测过程中能够提供自身性能数据的施压目标机器.管理执行机的节点.CPTS为用户的测试工程提供管理能力,事务.压测任务.测试报告的内容在同一个测试工程内共享复用, ...

  5. TCP 超时时间设置过长或 MTU 设置不合理会导致网络速度变慢吗

    是的,TCP 超时时间设置过长或 MTU 设置不合理都可能导致网络速度变慢. TCP 超时时间是指在发送数据之后,如果没有收到对端的应答,就会在超时时间后再次发送数据.如果超时时间设置过长,会导致发送 ...

  6. 联众服务器超时中断,http连接中客户端中断了请求,服务端会中断执行吗?超时时间设置?...

    由于http是基于tcp的,在tcp中,客户端中断了连接,服务端是无法感知的,只能通过发心跳包来检测,而显然我们的nginx是没有发心跳包的,所以,包括nginx,php-fpm都是不知道客户端已断开 ...

  7. 服务器时间修改连接超时时间,服务器设置网络连接超时时间设置

    服务器设置网络连接超时时间设置 内容精选 换一换 有以下几种现象:将制作好的SD卡插入开发者板并上电后,开发者板LED1与LED2灯状态信息异常.将制作好的SD卡插入开发者板,并通过USB方式连接Ub ...

  8. Feign Client的各种超时时间设置

    在Spring Cloud微服务架构中,大部分公司都是利用Open Feign进行服务间的调用,而比较简单的业务使用默认配置是不会有多大问题的,但是如果是业务比较复杂,服务要进行比较繁杂的业务计算,那 ...

  9. httpClient 超时时间设置

    上周乐视网cms香港接口,数据刷新缓慢.香港运营人员一直在群里反馈tv端内容不更新. 我观察了下服务器,发现请求接口耗时很久500-6000ms.之前一般都是100ms左右. 导致很多线程一直在wai ...

最新文章

  1. 代码详解 | 用Pytorch训练快速神经网络的9个技巧
  2. R语言使用download.file函数下载网络文件到本地(Download File from the Internet)
  3. 有多少智能,就有多少人工?人工智能背后的数据标注师
  4. python写入csv文件中文乱码解决方案
  5. 【Cocos2dx开发】精灵
  6. Android长度单位详解(dp、sp、px、in、pt、mm、dip)
  7. 数学--数论--HDU - 6322 打表找规律
  8. 同步监视器之同步代码块、同步方法
  9. 《Python自动化》学习笔记:百度云智能实现提取身份证信息
  10. java中switch、while、do...while、for
  11. STM32多个串口重定义
  12. 数据处理可视化的最有价值的 50 张图 (上)
  13. Compose的手势(六)
  14. 摄影构图学83年绝版_常用的摄影构图之点线面
  15. 探讨手机越狱和安装deb文件的几种方式研究
  16. jenkins如何清缓存,jenkins在结账前清除存储库并强制克隆与清理
  17. [llvm]查看O3使用了哪些pass
  18. 不可不看:管理定理一网打尽
  19. 设备加密有什么作用?
  20. 3.Maven 常用命令

热门文章

  1. Mysql:设置主键自动增长起始值
  2. 华山全敏还是全劲_一梦江湖华山加点_一梦江湖华山加点推荐2020_攻略
  3. 压缩感知稀疏基之离散余弦变换(DCT)和离散正弦变换(DST)
  4. 《数据库系统》(二) 关系数据库
  5. 关于计网的一点复习资料
  6. 网页商品SKU(规格)选择
  7. Amdahl(阿姆达尔定律) Law
  8. C#支付宝支付接口H5版(手机网页支付)
  9. 实现学生信息的多关键字排序
  10. java outputstream 输入文件损坏问题