本文档介绍在Android客户端上使用阿里云OSS SDK接入HTTPDNS的方案。
1. 背景说明
阿里云对象存储OSS(Object Storage Service)是一款通用的云存储服务,可让开发者在各类应用中便捷地存储和访问用户头像、图片、音视频等文件。在Android端,可以通过集成OSS Android SDK来完成。
为了提升文件传输的稳定性和速度,可以将HTTPDNS SDK与OSS Android SDK进行结合,对OSS域名进行解析。这可以有效实现域名防劫持和DNS解析加速,从而优化应用访问OSS的网络体验。
2. 基于OkHttp接入HTTPDNS SDK
实现OkHttp的自定义DNS接口,接入HTTPDNS,具体参考Android端HTTPDNS+OkHttp最佳实践。
class OkHttpDns constructor(context: Context): Dns {
private var mContext: Context
init {
mContext = context
}
@Throws(UnknownHostException::class)
override fun lookup(host: String): List<InetAddress> {
val httpdnsResult: HTTPDNSResult = HttpDns.getService(accountID)
.getHttpDnsResultForHostSync(host, RequestIpType.both)
val inetAddresses: MutableList<InetAddress> = ArrayList()
var address: InetAddress
try {
if (httpdnsResult.ips != null) {
//处理IPv4地址
for (ipv4 in httpdnsResult.ips) {
address = InetAddress.getByName(ipv4)
inetAddresses.add(address)
}
}
if (httpdnsResult.ipv6s != null) {
//处理IPv6地址
for (ipv6 in httpdnsResult.ipv6s) {
address = InetAddress.getByName(ipv6)
inetAddresses.add(address)
}
}
} catch (e: UnknownHostException) {
}
return if (!inetAddresses.isEmpty()) {
inetAddresses
} else Dns.SYSTEM.lookup(host)
}
}
public class OkHttpDns implements Dns {
private Context mContext;
public OkHttpDns(Context context) {
mContext = context;
}
@Overridepublic List<InetAddress> lookup(String host) throws UnknownHostException {
HTTPDNSResult httpdnsResult = HttpDns.getService(accountID).getHttpDnsResultForHostSync(host, RequestIpType.both);
List<InetAddress> inetAddresses = new ArrayList<>();
InetAddress address;
try {
if (httpdnsResult.getIps() != null) {
//处理IPv4地址for (String ipv4 : httpdnsResult.getIps()) {
address = InetAddress.getByName(ipv4);
inetAddresses.add(address);
}
}
if (httpdnsResult.getIpv6s() != null) {
//处理IPv6地址for (String ipv6 : httpdnsResult.getIpv6s()) {
address = InetAddress.getByName(ipv6);
inetAddresses.add(address);
}
}
} catch (UnknownHostException e) {
}
if (!inetAddresses.isEmpty()) {
return inetAddresses;
}
return okhttp3.Dns.SYSTEM.lookup(host);
}
}
3. 接入OSS SDK并使用HTTPDNS
创建OKHttpClient实例,并配置到OSS代替默认DNS服务。OSS SDK的接入和使用,可以参考OSS Android SDK。
// 创建OSS客户端配置
val conf = ClientConfiguration()
conf.connectionTimeout = 15 * 1000 // 连接超时,默认15秒。
conf.socketTimeout = 15 * 1000 // socket超时,默认15秒。
conf.maxConcurrentRequest = 5 // 最大并发请求书,默认5个。
conf.maxErrorRetry = 2 // 失败后最大重试次数,默认2次。
val builder = OkHttpClient.Builder()
.dns(OkHttpDns(applicationContext))
// 如果设置了自定义的okHttpClient,ClientConfiguration的部分设置将会失效。您需要将其手动设置到builder上。
if (conf != null) {
val dispatcher = Dispatcher()
dispatcher.maxRequests = conf.maxConcurrentRequest
builder.connectTimeout(conf.connectionTimeout.toLong(), TimeUnit.MILLISECONDS)
.readTimeout(conf.socketTimeout.toLong(), TimeUnit.MILLISECONDS)
.writeTimeout(conf.socketTimeout.toLong(), TimeUnit.MILLISECONDS)
.followRedirects(conf.isFollowRedirectsEnable)
.followSslRedirects(conf.isFollowRedirectsEnable)
.dispatcher(dispatcher)
if (conf.proxyHost != null && conf.proxyPort != 0) {
builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(conf.proxyHost, conf.proxyPort)))
}
}
// 仅Android OSS SDK 2.9.12或以上版本支持使用conf.setOkHttpClient()方法。
conf.okHttpClient = builder.build()
val oss = OSSClient(applicationContext, endpoint, credentialProvider, conf)
// 创建OSS客户端配置
ClientConfiguration conf = new ClientConfiguration();
conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒。
conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒。
conf.setMaxConcurrentRequest(5); // 最大并发请求书,默认5个。
conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次。
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.dns(new OkHttpDns(getApplicationContext()));
// 如果设置了自定义的okHttpClient,ClientConfiguration的部分设置将会失效。您需要将其手动设置到builder上。
if (conf != null) {
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(conf.getMaxConcurrentRequest());
builder.connectTimeout(conf.getConnectionTimeout(), TimeUnit.MILLISECONDS)
.readTimeout(conf.getSocketTimeout(), TimeUnit.MILLISECONDS)
.writeTimeout(conf.getSocketTimeout(), TimeUnit.MILLISECONDS)
.followRedirects(conf.isFollowRedirectsEnable())
.followSslRedirects(conf.isFollowRedirectsEnable())
.dispatcher(dispatcher);
if (conf.getProxyHost() != null && conf.getProxyPort() != 0) {
builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(conf.getProxyHost(), conf.getProxyPort())));
}
}
// 仅Android OSS SDK 2.9.12或以上版本支持使用conf.setOkHttpClient()方法。
conf.setOkHttpClient(builder.build());
OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider, conf);
重要
HTTPDNS SDK初始化设置需要在OSS SDK初始化设置之前完成。
4. 总结
通过将HTTPDNS与OSS SDK结合,可以有效防止DNS劫持并加速文件传输,提升访问的稳定性和安全性。
实现的核心是为OSS配置一个带有HTTPDNS解析逻辑的自定义OkHttpClient
。
关键注意点:
自定义
OkHttpClient
后,必须将ClientConfiguration
中的超时、并发数等配置手动设置到OkHttpClient.Builder
上,否则原配置会失效。请确保OSS SDK版本不低于2.9.12,并先初始化HTTPDNS,再初始化OSS。
该文章对您有帮助吗?