通过客户端接入概述您已经了解了HTTPDNS接入的基本原理,本文介绍通过Flutter SDK接入HTTPDNS的方法。
Flutter是Google开源的应用开发框架,仅通过一套代码库,就能构建精美的、原生平台编译的多平台应用。
我们提供纯 Dart 实现的 HTTPDNS SDK,无需依赖原生平台 SDK,并展示如何在Flutter常用的网络框架中集成使用HTTPDNS。本SDK已在GitHub和pub.dev发布。
以下是SDK的使用说明和最佳实践:
一、快速入门
1.1 开通服务
请参考快速入门开通HTTPDNS。
1.2 获取配置
请参考开发配置在EMAS控制台开发配置中获取AccountId/SecretKey/AESSecretKey等信息,用于初始化SDK。
二、安装配置
2.1 添加Flutter依赖
在您的Flutter项目的pubspec.yaml中加入dependencies:
dependencies:
flutter:
sdk: flutter
aliyun_httpdns: ^2.0.0 # 从SDK发布说明获取最新版本号
dio: ^5.9.0 # Dio网络库
http: ^1.2.0 # http包添加依赖之后需要执行一次 flutter pub get。
从 2.0.0 版本起,本 SDK 为纯 Dart 实现,无需配置 Android 或 iOS 原生依赖,安装后直接使用。
三、配置和使用
3.1 初始化配置
应用启动后,需要先初始化插件,才能调用HTTPDNS能力。 初始化主要是配置AccountId/SecretKey等信息及功能开关。 示例代码如下:
// 初始化 HTTPDNS
final config = AliyunHttpdnsConfig(
accountId: 您的AccountId,
secretKey: '您的SecretKey',
httpsEnabled: true,
persistentCacheEnabled: true,
reuseExpiredIPEnabled: true,
preResolveAfterNetworkChanged: true,
ipRankingDatasource: {
'www.aliyun.com': 443,
},
);
await AliyunHttpdns.init(config);
// 开启日志(可选)
AliyunHttpdns.setLogEnabled(true);
// 设置预解析域名
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com'], ipType: HttpdnsIpType.auto);3.1.1 日志配置
应用开发过程中,如果要输出HTTPDNS的日志,可以调用日志输出控制方法,开启日志,示例代码如下:
AliyunHttpdns.setLogEnabled(true);
// 自定义日志处理器(可选)
AliyunHttpdns.setLogHandler((message) {
print(message);
});3.1.2 sessionId记录
应用在运行过程中,可以调用获取SessionId方法获取sessionId,记录到应用的数据采集系统中。 sessionId用于表示标识一次应用运行,线上排查时,可以用于查询应用一次运行过程中的解析日志,示例代码如下:
final sessionId = AliyunHttpdns.getSessionId();
print("SessionId = $sessionId");3.2 域名解析
3.2.1 预解析
当需要提前解析域名时,可以调用预解析域名方法,示例代码如下:
await AliyunHttpdns.setPreResolveHosts(["www.aliyun.com", "www.example.com"], ipType: HttpdnsIpType.auto);调用之后,SDK会发起域名解析,并把结果缓存到内存,用于后续请求时直接使用。
3.2.2 域名解析
当需要解析域名时,可以通过调用域名解析方法解析域名获取IP,示例代码如下:
Future<void> _resolve() async {
final result = await AliyunHttpdns.resolveHostSyncNonBlocking('www.aliyun.com', ipType: HttpdnsIpType.auto);
final ipv4List = result?.ips ?? [];
final ipv6List = result?.ipv6s ?? [];
print('IPv4: $ipv4List');
print('IPv6: $ipv6List');
}四、Flutter最佳实践
4.1 原理说明
本示例展示了一种更直接的集成方式,通过自定义HTTP客户端适配器来实现HTTPDNS集成:
创建自定义的HTTP客户端适配器,拦截网络请求
在适配器中调用HTTPDNS插件解析域名为IP地址
使用解析得到的IP地址创建直接的Socket连接
对于HTTPS连接,确保正确设置SNI(Server Name Indication)为原始域名
这种方式直接在 HTTP 客户端层面集成 HTTPDNS 功能,实现简洁高效。
4.2 示例说明
本示例提供了一个完整的Flutter应用,展示如何集成HTTPDNS功能。
4.2.1 自定义HTTP客户端适配器实现
自定义适配器的实现请参考 lib/net/httpdns_http_client_adapter.dart 文件。本方案由EMAS团队设计实现,参考请注明出处。 适配器内部会拦截HTTP请求,调用HTTPDNS进行域名解析,并使用解析后的IP创建socket连接。
本示例支持三种网络库:Dio、HttpClient、http包。代码如下:
import 'dart:io';
import 'package:dio/io.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';
import 'package:flutter/foundation.dart';
import 'package:aliyun_httpdns/aliyun_httpdns.dart';
// Dio 适配器
IOHttpClientAdapter buildHttpdnsHttpClientAdapter() {
final HttpClient client = HttpClient();
_configureHttpClient(client);
_configureConnectionFactory(client);
final IOHttpClientAdapter adapter = IOHttpClientAdapter(createHttpClient: () => client)
..validateCertificate = (cert, host, port) => true;
return adapter;
}
// 原生 HttpClient
HttpClient buildHttpdnsNativeHttpClient() {
final HttpClient client = HttpClient();
_configureHttpClient(client);
_configureConnectionFactory(client);
return client;
}
// http 包适配器
http.Client buildHttpdnsHttpPackageClient() {
final HttpClient httpClient = buildHttpdnsNativeHttpClient();
return IOClient(httpClient);
}
// HttpClient 基础配置
void _configureHttpClient(HttpClient client) {
client.findProxy = (Uri _) => 'DIRECT';
client.idleTimeout = const Duration(seconds: 30);
client.maxConnectionsPerHost = 8;
}
// 配置基于 HTTPDNS 的连接工厂
// 本方案由EMAS团队设计实现,参考请注明出处。
void _configureConnectionFactory(HttpClient client) {
client.connectionFactory = (Uri uri, String? proxyHost, int? proxyPort) async {
final String domain = uri.host;
final bool https = uri.scheme.toLowerCase() == 'https';
final int port = uri.port == 0 ? (https ? 443 : 80) : uri.port;
final List<InternetAddress> targets = await _resolveTargets(domain);
final Object target = targets.isNotEmpty ? targets.first : domain;
if (!https) {
return Socket.startConnect(target, port);
}
// HTTPS:先 TCP,再 TLS(SNI=域名),并保持可取消
bool cancelled = false;
final Future<ConnectionTask<Socket>> rawStart = Socket.startConnect(target, port);
final Future<Socket> upgraded = rawStart.then((task) async {
final Socket raw = await task.socket;
if (cancelled) {
raw.destroy();
throw const SocketException('Connection cancelled');
}
final SecureSocket secure = await SecureSocket.secure(
raw,
host: domain, // 重要:使用原始域名作为SNI
);
if (cancelled) {
secure.destroy();
throw const SocketException('Connection cancelled');
}
return secure;
});
return ConnectionTask.fromSocket(
upgraded,
() {
cancelled = true;
try {
rawStart.then((t) => t.cancel());
} catch (_) {}
},
);
};
}
// 通过 HTTPDNS 解析目标 IP 列表
Future<List<InternetAddress>> _resolveTargets(String domain) async {
try {
final result = await AliyunHttpdns.resolveHostSyncNonBlocking(domain, ipType: HttpdnsIpType.auto);
final List<String> ipv4 = result?.ips ?? [];
final List<String> ipv6 = result?.ipv6s ?? [];
final List<InternetAddress> targets = [
...ipv4.map(InternetAddress.tryParse).whereType<InternetAddress>(),
...ipv6.map(InternetAddress.tryParse).whereType<InternetAddress>(),
];
if (targets.isEmpty) {
debugPrint('[dio] HTTPDNS no result for $domain, fallback to system DNS');
} else {
debugPrint('[dio] HTTPDNS resolved $domain -> ${targets.first.address}');
}
return targets;
} catch (e) {
debugPrint('[dio] HTTPDNS resolve failed: $e, fallback to system DNS');
return const <InternetAddress>[];
}
}4.2.2 适配器集成和使用
适配器的集成请参考 lib/main.dart 文件。 首先需要初始化HTTPDNS,然后配置网络库使用自定义适配器,示例代码如下:
class _MyHomePageState extends State<MyHomePage> {
late final Dio _dio;
late final HttpClient _httpClient;
late final http.Client _httpPackageClient;
@override
void initState() {
super.initState();
// 初始化 HTTPDNS
_initHttpDnsOnce();
// 配置网络库使用 HTTPDNS 适配器
_dio = Dio();
_dio.httpClientAdapter = buildHttpdnsHttpClientAdapter();
_dio.options.headers['Connection'] = 'keep-alive';
_httpClient = buildHttpdnsNativeHttpClient();
_httpPackageClient = buildHttpdnsHttpPackageClient();
}
Future<void> _initHttpDnsOnce() async {
try {
final config = AliyunHttpdnsConfig(
accountId: 您的AccountId,
secretKey: '您的SecretKey',
httpsEnabled: true,
reuseExpiredIPEnabled: true,
);
await AliyunHttpdns.init(config);
AliyunHttpdns.setLogEnabled(true);
// 设置预解析域名
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com'], ipType: HttpdnsIpType.auto);
} catch (e) {
debugPrint('[httpdns] init failed: $e');
}
}
}使用配置好的网络库发起请求时,会自动使用HTTPDNS进行域名解析:
// 使用 Dio
final response = await _dio.get('https://www.aliyun.com');
// 使用 HttpClient
final request = await _httpClient.getUrl(Uri.parse('https://www.aliyun.com'));
final response = await request.close();
// 使用 http 包
final response = await _httpPackageClient.get(Uri.parse('https://www.aliyun.com'));4.2.3 资源清理
在组件销毁时,记得清理相关资源:
@override
void dispose() {
_urlController.dispose();
_httpClient.close();
_httpPackageClient.close();
super.dispose();
}五、API
5.1 日志输出控制
控制是否打印Log。
AliyunHttpdns.setLogEnabled(true);5.2 初始化
初始化配置,在应用启动时调用。
// 创建配置
final config = AliyunHttpdnsConfig(
accountId: 您的AccountId, // 必填
secretKey: 'your_secret_key', // 可选
aesSecretKey: 'your_aes_secret_key', // 可选
region: HttpdnsRegion.cn, // 默认中国大陆
httpsEnabled: true, // 默认 true
persistentCacheEnabled: true, // 持久化缓存
reuseExpiredIPEnabled: true, // 复用过期 IP
preResolveAfterNetworkChanged: true, // 网络变化后预解析
ipRankingDatasource: { // IP 优选配置(可选)
'www.aliyun.com': 443,
},
timeout: 2, // 请求超时(秒)
);
// 初始化 SDK
await AliyunHttpdns.init(config);
// 开启日志(可选)
AliyunHttpdns.setLogEnabled(true);初始化参数:
参数名 | 类型 | 是否必须 | 功能 |
accountId | int | 必选参数 | Account ID |
secretKey | String? | 可选参数 | 加签密钥 |
aesSecretKey | String? | 可选参数 | 加密密钥 |
region | HttpdnsRegion | 可选参数 | 服务区域,默认 cn |
httpsEnabled | bool | 可选参数 | 是否使用HTTPS解析链路,默认 true |
persistentCacheEnabled | bool | 可选参数 | 是否开启持久化缓存,默认 false |
reuseExpiredIPEnabled | bool | 可选参数 | 是否允许复用过期IP,默认 false |
preResolveAfterNetworkChanged | bool | 可选参数 | 网络切换时是否自动刷新解析,默认 false |
discardExpiredAfterSeconds | int? | 可选参数 | 过期缓存丢弃时间(秒) |
ipRankingDatasource | Map<String, int>? | 可选参数 | IP优选配置,域名和端口的映射 |
timeout | int | 可选参数 | 请求超时时间(秒),默认 2 |
5.3 域名解析
解析指定域名。SDK 提供三种解析方式:
5.3.1 同步非阻塞解析(推荐)
立即返回缓存结果,缓存未命中时返回空并在后台发起请求。
final result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
);
// 带 SDNS 参数
final result2 = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
sdnsParams: {'key': 'value'},
cacheKey: 'custom_cache_key',
);5.3.2 同步阻塞解析
阻塞等待直到获取结果或超时。
final result = await AliyunHttpdns.resolveHostSync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
);
// 带 SDNS 参数
final result2 = await AliyunHttpdns.resolveHostSync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
sdnsParams: {'key': 'value'},
cacheKey: 'custom_cache_key',
);5.3.3 异步回调解析
通过回调函数返回解析结果。
await AliyunHttpdns.resolveHostAsync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
callback: (result) {
print('解析结果: $result');
},
);
// 带 SDNS 参数
await AliyunHttpdns.resolveHostAsync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
sdnsParams: {'key': 'value'},
cacheKey: 'custom_cache_key',
callback: (result) {
print('解析结果: $result');
},
);解析参数说明
参数名 | 类型 | 是否必须 | 功能 |
host | String | 必选参数 | 要解析的域名 |
ipType | HttpdnsIpType | 可选参数 | 请求IP类型:auto, v4, v6, both |
sdnsParams | Map<String, String>? | 可选参数 | SDNS参数,用于自定义解析 |
cacheKey | String? | 可选参数 | 自定义缓存Key |
返回数据结构 (ResolveResult)
字段名 | 类型 | 功能 |
host | String | 域名 |
ips | List | IPv4地址列表 |
ipv6s | List | IPv6地址列表 |
ttl | int | IPv4 TTL(秒) |
v6ttl | int | IPv6 TTL(秒) |
5.4 预解析域名
预解析域名,解析后缓存在SDK中,下次解析时直接从缓存中获取,提高解析速度。
await AliyunHttpdns.setPreResolveHosts(
["www.aliyun.com"],
ipType: HttpdnsIpType.auto
);参数:
参数名 | 类型 | 是否必须 | 功能 |
hosts | List | 必选参数 | 预解析域名列表 |
ipType | HttpdnsIpType | 可选参数 | 请求IP类型:auto, v4, v6, both |
5.5 获取SessionId
获取SessionId,用于排查追踪问题。
final sessionId = await AliyunHttpdns.getSessionId();
print("SessionId = $sessionId");无需参数,直接返回当前会话ID。
5.6 清除缓存
清除DNS解析缓存。
// 清除所有缓存
await AliyunHttpdns.cleanHostCache(null);
// 清除指定域名缓存
await AliyunHttpdns.cleanHostCache(['www.aliyun.com']);5.7 网络变化时自动刷新预解析
设置在网络环境变化时是否自动刷新预解析域名的缓存,通过初始化配置设置。
final config = AliyunHttpdnsConfig(
accountId: 您的AccountId,
secretKey: 'your_secret_key',
preResolveAfterNetworkChanged: true, // 网络变化时自动刷新
);
await AliyunHttpdns.init(config);5.8 持久化缓存配置
设置是否开启持久化缓存功能。开启后,SDK 会将解析结果保存到本地,App 重启后可以从本地加载缓存。通过初始化配置设置。
final config = AliyunHttpdnsConfig(
accountId: 您的AccountId,
secretKey: 'your_secret_key',
persistentCacheEnabled: true, // 开启持久化缓存
discardExpiredAfterSeconds: 86400, // 可选,过期超过1天的缓存丢弃
);
await AliyunHttpdns.init(config);参数:
参数名 | 类型 | 是否必须 | 功能 |
persistentCacheEnabled | bool | 可选参数 | 是否开启持久化缓存,默认 false |
discardExpiredAfterSeconds | int? | 可选参数 | 过期时间阈值(秒),App 启动时会丢弃过期超过此时长的缓存记录 |
5.9 IP 优选
设置需要进行 IP 优选的域名列表。开启后,SDK 会对解析返回的 IP 列表进行 TCP 测速并排序,以保证第一个 IP 是可用性最好的 IP。通过初始化配置设置:
final config = AliyunHttpdnsConfig(
accountId: 您的AccountId,
secretKey: 'your_secret_key',
ipRankingDatasource: {
'www.aliyun.com': 443,
},
);
await AliyunHttpdns.init(config);参数:
参数名 | 类型 | 是否必须 | 功能 |
ipRankingDatasource | Map<String, int>? | 可选参数 | 域名和端口的映射,如:{'www.aliyun.com': 443} |
5.10 自定义 TTL
可以通过设置回调函数来修改解析结果的 TTL。
AliyunHttpdns.setTtlChanger((host, ipType, ttl) {
// 返回修改后的 TTL
return ttl * 2;
});5.11 SDNS 全局参数
设置全局 SDNS 参数,所有解析请求都会携带这些参数。
AliyunHttpdns.setSdnsGlobalParams({
'key1': 'value1',
'key2': 'value2',
});5.12 校正签名时间
当客户端时间与服务器时间不一致时,可通过此方法校准时间。
AliyunHttpdns.setAuthCurrentTime(serverTimestamp);六、版本升级指南
6.1 版本 1.x 升级到 2.0.0 指南
2.0.0 版本重构为纯 Dart 实现,主要优势:
无需依赖 Android/iOS 原生 SDK,简化项目配置和版本管理
跨平台行为一致,更易调试和维护
减少包体积,无原生桥接开销
本次升级涉及部分 API 变化,主要是初始化方式和参数类型的调整。按照下面的步骤操作即可完成升级。
升级步骤详解
1. 更新依赖版本
pubspec.yaml
dependencies:aliyun_httpdns: ^2.0.0执行更新:
flutter pub upgrade aliyun_httpdns2.0.0 为纯 Dart 实现,可以删除项目中与原生 SDK 相关的配置(如 build.gradle 中的 HTTPDNS 依赖、podspec 中的 AlicloudHTTPDNS 依赖)。
2. 重构初始化代码
升级前(1.x)
// 1.x:两阶段初始化
await AliyunHttpdns.init(
accountId: 您的AccountId,
secretKey: "your_secret_key",
aesSecretKey: "your_aes_key",
);
await AliyunHttpdns.setHttpsRequestEnabled(true);
await AliyunHttpdns.setPersistentCacheIPEnabled(true);
await AliyunHttpdns.setReuseExpiredIPEnabled(true);
await AliyunHttpdns.setPreResolveAfterNetworkChanged(true);
await AliyunHttpdns.setIPRankingList({'www.aliyun.com': 443});
await AliyunHttpdns.build();升级后(2.0)
final config = AliyunHttpdnsConfig(
accountId: 您的AccountId,
secretKey: 'your_secret_key',
aesSecretKey: 'your_aes_key',
httpsEnabled: true,
persistentCacheEnabled: true,
reuseExpiredIPEnabled: true,
preResolveAfterNetworkChanged: true,
ipRankingDatasource: {'www.aliyun.com': 443},
);
await AliyunHttpdns.init(config);说明 :
所有功能配置合并到
AliyunHttpdnsConfig构造参数中不再需要调用
build()方法新增
region、timeout、discardExpiredAfterSeconds等配置参数
3. 更新解析接口
升级前(1.x)
final res = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: 'both',
);
final ipv4s = res['ipv4'] ?? [];
final ipv6s = res['ipv6'] ?? [];升级后(2.0)
final result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
);
final ipv4s = result?.ips ?? [];
final ipv6s = result?.ipv6s ?? [];说明 :
ipType从字符串改为HttpdnsIpType枚举(auto, v4, v6, both)返回值从
Map<String, List<String>>改为ResolveResult?对象字段名从
ipv4/ipv6改为ips/ipv6s新增
resolveHostSync和resolveHostAsync两种解析方式
4. 更新预解析接口
升级前(1.x)
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com']);升级后(2.0)
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com']);5. 新增自定义日志处理器
AliyunHttpdns.setLogHandler((message) {
print(message);
});6. 更新清除缓存接口
升级前(1.x)
await AliyunHttpdns.cleanAllHostCache();升级后(2.0)
// 清除所有缓存
await AliyunHttpdns.cleanHostCache(null);
// 清除指定域名缓存(新增)
await AliyunHttpdns.cleanHostCache(['www.aliyun.com']);若您的应用未使用到变化的 API,可以不用处理。
API 升级映射表(1.x → 2.0)
接口分类 | 1.x | 2.0 |
初始化 |
|
|
启用 HTTPS 请求 |
|
|
启用过期 IP |
|
|
开启本地缓存 |
|
|
网络切换预解析 |
|
|
IP 优选 |
|
|
构建服务 |
| 不再需要 |
同步非阻塞解析 |
|
|
同步阻塞解析 | 无 |
|
异步回调解析 | 无 |
|
返回值 |
|
|
设置预解析域名 |
|
|
清除缓存 |
|
|
自定义 TTL | 无 |
|
SDNS 全局参数 | 无 |
|
自定义日志处理器 | 无 |
|
校正签名时间 | 无 |
|
6.2 版本 0.x 升级到 1.0.0 指南
1.0.0 版本进行了全面的架构重构和接口优化。这次升级旨在:
统一配置模式:从分散的运行时配置改为两阶段初始化模式(init + build),解决配置时序问题,提升 SDK 稳定性
标准化解析接口:重新设计解析接口架构,提供统一的
resolveHostSyncNonBlocking方法,返回结构化数据而非 JSON 字符串静态方法设计:从单例模式改为静态方法调用,简化使用方式,无需创建实例
性能优化:通过接口优化和内部实现改进,提升解析性能和资源利用效率
这是一次不兼容的重大变更,虽然变更较大,但您只需要修改应用中实际使用的接口。通过下面的升级步骤和新旧 API 映射表,您可以系统性地完成这次重要升级。
升级步骤详解
1. 更新依赖版本
pubspec.yaml
dependencies:aliyun_httpdns: ^1.0.0执行更新:
flutter pub upgrade aliyun_httpdns2. 重构初始化代码
升级前
// 旧版本:单例模式 + 一步初始化
final _aliyunHttpDns = AliyunHttpDns();
await _aliyunHttpDns.init(
"YOUR_ACCOUNT_ID", // String 类型
secretKey: "your_secret_key",
aesSecretKey: "your_aes_key",
region: "",
timeout: 2000,
enableHttps: true,
enableExpireIp: true,
enableCacheIp: true,
enableDegradationLocalDns: true,
preResolveAfterNetworkChanged: true,
ipRankingMap: {"www.aliyun.com": 80},
sdnsGlobalParam: {"aa": "bb"},
bizTags: ["tag1", "tag2"]
);升级后
// 新版本:静态方法 + 两阶段初始化
// 第一阶段:初始化基本配置
await AliyunHttpdns.init(
accountId: your_account_id, // int 类型,必须设置
secretKey: "your_secret_key", // 可选
aesSecretKey: "your_aes_key", // 可选
);
// 第二阶段:设置功能选项
await AliyunHttpdns.setHttpsRequestEnabled(true); // 替代 enableHttps
await AliyunHttpdns.setLogEnabled(true); // 替代 enableLog
await AliyunHttpdns.setPersistentCacheIPEnabled(true); // 替代 enableCacheIp
await AliyunHttpdns.setReuseExpiredIPEnabled(true); // 替代 enableExpireIp
await AliyunHttpdns.setPreResolveAfterNetworkChanged(true); // 替代 preResolveAfterNetworkChanged
// 第三阶段:构建服务(必须调用)
await AliyunHttpdns.build();说明:
移除了
region、timeout、enableDegradationLocalDns、ipRankingMap、sdnsGlobalParam、bizTags等参数新增
build()方法,必须在配置完成后调用所有方法改为静态方法,无需创建实例
3. 更新解析接口
升级前
// 同步非阻塞,返回 JSON 字符串
String result = await _aliyunHttpDns.resolve(
"YOUR_ACCOUNT_ID", // accountId
"www.aliyun.com", // host
kRequestIpv4AndIpv6, // requestIpType
);
// 需要手动解析 JSON
Map<String, dynamic> map = json.decode(result);
List<String> ipv4s = List<String>.from(map['ipv4'] ?? []);
List<String> ipv6s = List<String>.from(map['ipv6'] ?? []);
// 使用第一个 IP
String ip = ipv4s.isNotEmpty ? ipv4s.first : '';升级后
// 同步非阻塞,返回结构化数据
Map<String, List<String>> result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com', // hostname(无需 accountId)
ipType: 'both', // 替代 kRequestIpv4AndIpv6
);
// 直接获取 IP 列表
List<String> ipv4s = result['ipv4'] ?? [];
List<String> ipv6s = result['ipv6'] ?? [];
// 使用第一个 IP
String ip = ipv4s.isNotEmpty ? ipv4s.first : '';自定义解析参数:
// 升级前
String result = await _aliyunHttpDns.resolve(
"YOUR_ACCOUNT_ID",
"www.aliyun.com",
kRequestIpv4AndIpv6,
params: {"key": "value"},
cacheKey: "custom_key"
);
// 升级后
Map<String, List<String>> result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: 'both',
sdnsParams: {"key": "value"}, // 参数名变更
cacheKey: "custom_key"
);4. 更新预解析接口
升级前
await _aliyunHttpDns.setPreResolveHosts(
"YOUR_ACCOUNT_ID", // accountId
["www.aliyun.com"],
kRequestIpv4AndIpv6 // requestIpType
);升级后
await AliyunHttpdns.setPreResolveHosts(
["www.aliyun.com"], // 无需 accountId
ipType: 'both' // 替代 kRequestIpv4AndIpv6
);5. 更新日志配置
升级前
await _aliyunHttpDns.enableLog(true);升级后
await AliyunHttpdns.setLogEnabled(true);6. 更新 SessionId 获取
升级前
String sessionId = await _aliyunHttpDns.getSessionId("YOUR_ACCOUNT_ID");升级后
String? sessionId = await AliyunHttpdns.getSessionId();7. 新增功能使用
清除缓存
await AliyunHttpdns.cleanAllHostCache();持久化缓存配置
await AliyunHttpdns.setPersistentCacheIPEnabled(true);若您的应用未使用到不兼容的 API,可以不用处理。
API 升级映射表
接口分类 | 升级前 | 升级后 |
创建实例 |
| 无需创建,直接使用静态方法 |
初始化 |
|
|
构建服务 | 无 |
|
启用 HTTPS 请求 |
|
|
启用过期 IP |
|
|
开启本地缓存 |
|
|
网络切换预解析 |
|
|
控制日志输出 |
|
|
同步非阻塞解析 |
|
|
IPv4 解析 |
|
|
IPv6 解析 |
|
|
IPv4 和 IPv6 解析 |
|
|
自动选择 | 无 |
|
自定义解析参数 |
|
|
设置预解析域名 |
|
|
获取 SessionId |
|
|
清除缓存 | 无 |
|
校正签名时间 |
| 已移除 |