Topik ini menjelaskan cara mengintegrasikan HTTPDNS menggunakan Flutter SDK. Untuk informasi mengenai prinsip dasar integrasi HTTPDNS, lihat Client Integration Overview.
Flutter adalah framework pengembangan aplikasi open-source dari Google yang memungkinkan Anda membuat aplikasi multi-platform yang indah dan dikompilasi secara native dari satu basis kode.
Kami menyediakan SDK HTTPDNS murni Dart yang tidak memerlukan SDK platform native. Topik ini juga menunjukkan cara mengintegrasikan dan menggunakan HTTPDNS dalam framework jaringan Flutter umum. SDK ini tersedia di GitHub dan pub.dev.
Bagian berikut memberikan petunjuk dan praktik terbaik untuk menggunakan SDK:
1. Memulai
1.1. Aktifkan layanan
Untuk mengaktifkan HTTPDNS, lihat Quick Start.
1.2. Dapatkan konfigurasi
Dapatkan AccountId, SecretKey, dan AESSecretKey Anda dari konfigurasi pengembangan di Konsol EMAS. Informasi ini diperlukan untuk menginisialisasi software development kit (SDK). Untuk informasi lebih lanjut, lihat Development configurations.
2. Instalasi dan konfigurasi
2.1. Tambahkan dependensi Flutter
Pada file pubspec.yaml proyek Flutter Anda, tambahkan dependensi berikut:
dependencies:
flutter:
sdk: flutter
aliyun_httpdns: ^2.0.0 # Dapatkan nomor versi terbaru dari catatan rilis SDK
dio: ^5.9.0 # Library jaringan Dio
http: ^1.2.0 # Paket httpSetelah menambahkan dependensi, jalankan flutter pub get.
Mulai dari versi 2.0.0, SDK ini merupakan implementasi murni Dart. SDK ini tidak memerlukan dependensi native Android atau iOS dan dapat langsung digunakan setelah instalasi.
3. Konfigurasi dan penggunaan
3.1. Konfigurasi inisialisasi
Setelah aplikasi dimulai, Anda harus menginisialisasi plugin sebelum dapat menggunakan fitur HTTPDNS. Proses inisialisasi melibatkan konfigurasi AccountId, SecretKey, dan pengaturan lainnya, serta mengaktifkan fitur-fitur tersebut. Kode berikut memberikan contoh:
// Inisialisasi HTTPDNS
final config = AliyunHttpdnsConfig(
accountId: Your AccountId,
secretKey: 'Your SecretKey',
httpsEnabled: true,
persistentCacheEnabled: true,
reuseExpiredIPEnabled: true,
preResolveAfterNetworkChanged: true,
ipRankingDatasource: {
'www.aliyun.com': 443,
},
);
await AliyunHttpdns.init(config);
// Aktifkan logging (opsional)
AliyunHttpdns.setLogEnabled(true);
// Tetapkan host untuk pre-resolve
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com'], ipType: HttpdnsIpType.auto);Jika Anda mengatur parameter httpsEnabled ke true, penagihan Anda akan meningkat. Untuk informasi lebih lanjut, lihat Billing.
Jika Anda memiliki persyaratan keamanan tinggi untuk informasi nama domain atau parameter SDNS, Anda dapat mengonfigurasi parameter aesSecretKey untuk mengaktifkan enkripsi lapisan konten pada permintaan resolusi. Penggunaan enkripsi konten akan meningkatkan penagihan Anda. Untuk informasi lebih lanjut, lihat Billing.
3.1.1. Konfigurasi log
Untuk mengeluarkan log HTTPDNS selama pengembangan aplikasi, Anda dapat memanggil metode kontrol output log untuk mengaktifkan logging. Kode berikut memberikan contoh:
AliyunHttpdns.setLogEnabled(true);
// Penangan log kustom (opsional)
AliyunHttpdns.setLogHandler((message) {
print(message);
});3.1.2. Pencatatan SessionId
Saat aplikasi berjalan, Anda dapat memanggil metode untuk mengambil sessionId dan mencatatnya dalam sistem pengumpulan data aplikasi Anda. SessionId mengidentifikasi satu kali proses aplikasi dan dapat digunakan untuk mengkueri log resolusi untuk proses tertentu selama troubleshooting online. Kode berikut memberikan contoh:
final sessionId = AliyunHttpdns.getSessionId();
print("SessionId = $sessionId");3.2. Resolusi nama domain
3.2.1. Preresolusi
Saat Anda perlu melakukan resolusi nama domain sebelumnya, Anda dapat memanggil metode pre-resolve. Kode berikut memberikan contoh:
await AliyunHttpdns.setPreResolveHosts(["www.aliyun.com", "www.example.com"], ipType: HttpdnsIpType.auto);Setelah pemanggilan, SDK akan memulai resolusi nama domain dan menyimpan hasilnya dalam cache memori. Permintaan berikutnya kemudian dapat menggunakan hasil yang telah di-cache tersebut.
3.2.2. Resolusi nama domain
Saat Anda perlu melakukan resolusi nama domain, Anda dapat memanggil metode resolusi nama domain untuk mengambil alamat IP. Kode berikut memberikan contoh:
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');
}4. Praktik terbaik Flutter
4.1. Cara kerja
Contoh ini menunjukkan cara yang lebih langsung untuk mengintegrasikan HTTPDNS dengan mengimplementasikan adapter klien HTTP kustom:
Buat adapter klien HTTP kustom untuk mengintersepsi permintaan jaringan.
Dalam adapter tersebut, panggil plugin HTTPDNS untuk melakukan resolusi nama domain ke alamat IP.
Gunakan alamat IP yang telah diresolusi untuk membuat koneksi socket langsung.
Untuk koneksi HTTPS, pastikan Server Name Indication (SNI) diatur dengan benar ke nama domain asli.
Metode ini secara langsung mengintegrasikan fitur HTTPDNS pada level klien HTTP untuk implementasi yang sederhana dan efisien.
4.2. Contoh
Contoh ini menyediakan aplikasi Flutter lengkap yang menunjukkan cara mengintegrasikan fitur HTTPDNS.
4.2.1. Implementasi adapter klien HTTP kustom
Untuk implementasi adapter kustom, lihat file lib/net/httpdns_http_client_adapter.dart. Solusi ini dirancang dan diimplementasikan oleh tim EMAS. Jika Anda merujuk solusi ini, harap cantumkan atribusi. Adapter ini mengintersepsi permintaan HTTP, memanggil HTTPDNS untuk resolusi nama domain, dan menggunakan alamat IP yang telah diresolusi untuk membuat koneksi socket.
Contoh ini mendukung tiga library jaringan: Dio, HttpClient, dan paket http. Kodenya sebagai berikut:
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';
// Adapter 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 native
HttpClient buildHttpdnsNativeHttpClient() {
final HttpClient client = HttpClient();
_configureHttpClient(client);
_configureConnectionFactory(client);
return client;
}
// Adapter paket http
http.Client buildHttpdnsHttpPackageClient() {
final HttpClient httpClient = buildHttpdnsNativeHttpClient();
return IOClient(httpClient);
}
// Konfigurasi dasar HttpClient
void _configureHttpClient(HttpClient client) {
client.findProxy = (Uri _) => 'DIRECT';
client.idleTimeout = const Duration(seconds: 30);
client.maxConnectionsPerHost = 8;
}
// Konfigurasikan connection factory berdasarkan HTTPDNS
// Solusi ini dirancang dan diimplementasikan oleh tim EMAS. Cantumkan atribusi jika Anda merujuknya.
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: Pertama TCP, lalu TLS (SNI=nama domain), dan tetap bisa dibatalkan
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, // Penting: Gunakan nama domain asli sebagai 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 (_) {}
},
);
};
}
// Resolusi daftar IP target melalui HTTPDNS
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. Integrasi dan penggunaan adapter
Untuk integrasi adapter, lihat file lib/main.dart. Pertama, inisialisasi HTTPDNS. Kemudian, konfigurasikan library jaringan untuk menggunakan adapter kustom. Kode berikut memberikan contoh:
class _MyHomePageState extends State<MyHomePage> {
late final Dio _dio;
late final HttpClient _httpClient;
late final http.Client _httpPackageClient;
@override
void initState() {
super.initState();
// Inisialisasi HTTPDNS
_initHttpDnsOnce();
// Konfigurasikan library jaringan untuk menggunakan adapter 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: Your AccountId,
secretKey: 'Your SecretKey',
httpsEnabled: true,
reuseExpiredIPEnabled: true,
);
await AliyunHttpdns.init(config);
AliyunHttpdns.setLogEnabled(true);
// Tetapkan host untuk pre-resolve
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com'], ipType: HttpdnsIpType.auto);
} catch (e) {
debugPrint('[httpdns] init failed: $e');
}
}
}Saat Anda menggunakan library jaringan yang telah dikonfigurasi untuk membuat permintaan, library tersebut secara otomatis menggunakan HTTPDNS untuk resolusi nama domain:
// Gunakan Dio
final response = await _dio.get('https://www.aliyun.com');
// Gunakan HttpClient
final request = await _httpClient.getUrl(Uri.parse('https://www.aliyun.com'));
final response = await request.close();
// Gunakan paket http
final response = await _httpPackageClient.get(Uri.parse('https://www.aliyun.com'));4.2.3. Bersihkan resource
Saat komponen dihapus, Anda harus membersihkan resource terkait:
@override
void dispose() {
_urlController.dispose();
_httpClient.close();
_httpPackageClient.close();
super.dispose();
}5. API
5.1. Kontrol output log
Mengontrol apakah log dicetak atau tidak.
AliyunHttpdns.setLogEnabled(true);5.2. Inisialisasi
Metode ini menginisialisasi konfigurasi dan harus dipanggil saat aplikasi dimulai.
// Buat konfigurasi
final config = AliyunHttpdnsConfig(
accountId: Your AccountId, // Wajib diisi
secretKey: 'your_secret_key', // Opsional
aesSecretKey: 'your_aes_secret_key', // Opsional
region: HttpdnsRegion.cn, // Default: daratan Tiongkok
httpsEnabled: true, // Default: true
persistentCacheEnabled: true, // Cache persisten
reuseExpiredIPEnabled: true, // Gunakan kembali IP yang kedaluwarsa
preResolveAfterNetworkChanged: true, // Pre-resolve setelah perubahan jaringan
ipRankingDatasource: { // Konfigurasi peringkat IP (opsional)
'www.aliyun.com': 443,
},
timeout: 2, // Timeout permintaan (detik)
);
// Inisialisasi SDK
await AliyunHttpdns.init(config);
// Aktifkan logging (opsional)
AliyunHttpdns.setLogEnabled(true);Parameter inisialisasi:
Nama Parameter | Tipe | Wajib | Fitur |
accountId | int | Parameter wajib | ID Akun |
secretKey | String? | Parameter opsional | Kunci untuk menambahkan signature. |
aesSecretKey | String? | Parameter opsional | Kunci untuk mengenkripsi data. |
region | HttpdnsRegion | Parameter Opsional | Wilayah layanan tempat endpoint dideploy. Default: cn. |
httpsEnabled | bool | Parameter opsional | Menentukan apakah akan menggunakan tautan resolusi HTTPS. Default: true. |
persistentCacheEnabled | bool | Parameter opsional | Menentukan apakah akan mengaktifkan cache persisten. Default: false. |
reuseExpiredIPEnabled | bool | Parameter opsional | Menentukan apakah akan mengizinkan penggunaan kembali alamat IP yang kedaluwarsa. Default: false. |
preResolveAfterNetworkChanged | bool | Parameter opsional | Menentukan apakah akan secara otomatis merefresh resolusi saat jaringan berubah. Default: false. |
discardExpiredAfterSeconds | int? | Parameter opsional | Waktu kedaluwarsa untuk membuang data cache, dalam detik. |
ipRankingDatasource | Map<String, int>? | Parameter opsional | Konfigurasi peringkat IP. Peta nama domain dan port. |
timeout | int | Parameter opsional | Durasi timeout permintaan dalam detik. Default: 2. |
Jika Anda mengatur parameter httpsEnabled ke true, penagihan Anda akan meningkat. Untuk informasi lebih lanjut, lihat Billing.
Jika Anda memiliki persyaratan keamanan tinggi untuk informasi nama domain atau parameter Secure DNS (SDNS), Anda dapat mengonfigurasi parameter aesSecretKey untuk mengaktifkan enkripsi lapisan konten pada permintaan resolusi. Mengaktifkan enkripsi konten akan meningkatkan penagihan Anda. Untuk informasi lebih lanjut, lihat Billing.
5.3. Resolusi nama domain
Meresolusi nama domain tertentu. SDK menyediakan tiga metode resolusi:
5.3.1 Resolusi sinkron non-blocking (direkomendasikan)
Segera mengembalikan hasil cache. Jika cache tidak ditemukan, mengembalikan null dan memulai permintaan di latar belakang.
final result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
);
// Dengan parameter SDNS
final result2 = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
sdnsParams: {'key': 'value'},
cacheKey: 'custom_cache_key',
);5.3.2 Resolusi sinkron blocking
Menunggu hingga hasil diperoleh atau permintaan timeout.
final result = await AliyunHttpdns.resolveHostSync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
);
// Dengan parameter SDNS
final result2 = await AliyunHttpdns.resolveHostSync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
sdnsParams: {'key': 'value'},
cacheKey: 'custom_cache_key',
);5.3.3 Resolusi callback asinkron
Mengembalikan hasil resolusi melalui fungsi callback.
await AliyunHttpdns.resolveHostAsync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
callback: (result) {
print('Hasil resolusi: $result');
},
);
// Dengan parameter SDNS
await AliyunHttpdns.resolveHostAsync(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
sdnsParams: {'key': 'value'},
cacheKey: 'custom_cache_key',
callback: (result) {
print('Hasil resolusi: $result');
},
);Deskripsi parameter
Nama parameter | Tipe | Wajib | Fitur |
host | String | Parameter wajib | Nama domain yang akan diresolusi. |
ipType | HttpdnsIpType | Parameter opsional | Tipe IP yang diminta: auto, v4, v6, atau both. |
sdnsParams | Map<String, String>? | Parameter opsional | Parameter SDNS untuk resolusi kustom. |
cacheKey | String? | Parameter ini opsional. | Kunci cache kustom. |
Struktur data yang dikembalikan (ResolveResult)
Nama Bidang | Jenis | Fitur |
host | String | Nama domain. |
ips | List | Daftar alamat IPv4. |
ipv6s | List | Daftar alamat IPv6. |
ttl | int | TTL IPv4 dalam detik. |
v6ttl | int | TTL IPv6 dalam detik. |
5.4. Pre-resolve nama domain
Pre-resolve satu atau beberapa nama domain dan menyimpan hasilnya dalam cache SDK. Permintaan resolusi berikutnya untuk domain-domain tersebut dapat langsung mengambil hasil dari cache, sehingga meningkatkan kecepatan resolusi.
await AliyunHttpdns.setPreResolveHosts(
["www.aliyun.com"],
ipType: HttpdnsIpType.auto
);Parameter:
Nama parameter | Tipe | Wajib | Fitur |
hosts | List | Parameter wajib | Daftar nama domain yang akan di-pre-resolve. |
ipType | HttpdnsIpType | Parameter opsional | Tipe IP yang diminta: auto, v4, v6, atau both. |
5.5. Dapatkan SessionId
Mengambil SessionId, yang digunakan untuk troubleshooting dan pelacakan masalah.
final sessionId = await AliyunHttpdns.getSessionId();
print("SessionId = $sessionId");Tidak ada parameter yang diperlukan. Mengembalikan ID sesi saat ini.
5.6. Bersihkan cache
Membersihkan cache resolusi DNS.
// Bersihkan semua cache
await AliyunHttpdns.cleanHostCache(null);
// Bersihkan cache untuk nama domain tertentu
await AliyunHttpdns.cleanHostCache(['www.aliyun.com']);5.7. Refresh otomatis domain yang telah di-pre-resolve saat jaringan berubah
Menetapkan apakah akan secara otomatis merefresh cache untuk nama domain yang telah di-pre-resolve saat lingkungan jaringan berubah. Ini diatur melalui konfigurasi inisialisasi.
final config = AliyunHttpdnsConfig(
accountId: Your AccountId,
secretKey: 'your_secret_key',
preResolveAfterNetworkChanged: true, // Refresh otomatis saat jaringan berubah
);
await AliyunHttpdns.init(config);5.8. Konfigurasi cache persisten
Menetapkan apakah akan mengaktifkan fitur cache persisten. Saat diaktifkan, SDK menyimpan hasil resolusi ke perangkat lokal. Setelah aplikasi dimulai ulang, SDK dapat memuat hasil cache dari perangkat lokal. Ini diatur melalui konfigurasi inisialisasi.
final config = AliyunHttpdnsConfig(
accountId: Your AccountId,
secretKey: 'your_secret_key',
persistentCacheEnabled: true, // Aktifkan cache persisten
discardExpiredAfterSeconds: 86400, // Opsional, buang cache yang kedaluwarsa lebih dari 1 hari
);
await AliyunHttpdns.init(config);Parameter:
Nama Parameter | Tipe | Wajib | Fitur |
persistentCacheEnabled | bool | Parameter opsional | Menentukan apakah akan mengaktifkan cache persisten. Default: false. |
discardExpiredAfterSeconds | int? | Parameter opsional | Ambang batas kedaluwarsa dalam detik. Saat aplikasi dimulai, cache yang telah kedaluwarsa lebih lama dari durasi ini akan dibuang. |
5.9 Preferensi IP
Menentukan daftar nama domain yang akan menjalani peringkat IP. Saat diaktifkan, SDK melakukan tes kecepatan TCP pada alamat IP yang diresolusi dan mengurutkannya untuk memastikan alamat IP pertama dalam daftar memiliki ketersediaan terbaik. Ini diatur melalui konfigurasi inisialisasi:
final config = AliyunHttpdnsConfig(
accountId: Your AccountId,
secretKey: 'your_secret_key',
ipRankingDatasource: {
'www.aliyun.com': 443,
},
);
await AliyunHttpdns.init(config);Parameter:
Nama parameter | Tipe | Wajib | Fitur |
ipRankingDatasource | Map<String, int>? | Parameter opsional | Peta nama domain dan port, seperti {'www.aliyun.com': 443}. |
5.10 TTL kustom
Anda dapat menetapkan fungsi callback untuk memodifikasi TTL dari hasil resolusi.
AliyunHttpdns.setTtlChanger((host, ipType, ttl) {
// Kembalikan TTL yang telah dimodifikasi
return ttl * 2;
});5.11 Parameter global SDNS
Menetapkan parameter global SDNS. Semua permintaan resolusi akan membawa parameter-parameter ini.
AliyunHttpdns.setSdnsGlobalParams({
'key1': 'value1',
'key2': 'value2',
});5.12 Koreksi waktu tanda tangan
Jika waktu klien tidak konsisten dengan waktu server, Anda dapat menggunakan metode ini untuk mengkalibrasi waktu.
AliyunHttpdns.setAuthCurrentTime(serverTimestamp);6. Panduan peningkatan versi
6.1 Panduan peningkatan dari versi 1.x ke 2.0.0
Versi 2.0.0 direfaktor menjadi implementasi murni Dart. Keunggulan utamanya adalah:
Tidak bergantung pada SDK native Android atau iOS, yang menyederhanakan konfigurasi proyek dan manajemen versi.
Perilaku lintas platform yang konsisten, yang mempermudah debugging dan maintenance.
Ukuran paket berkurang dan tidak ada overhead native bridge.
Peningkatan ini melibatkan beberapa perubahan API, terutama pada metode inisialisasi dan tipe parameter. Ikuti langkah-langkah berikut untuk menyelesaikan peningkatan.
Langkah-langkah peningkatan detail
1. Perbarui versi dependensi
pubspec.yaml
dependencies:aliyun_httpdns: ^2.0.0Jalankan pembaruan:
flutter pub upgrade aliyun_httpdnsVersi 2.0.0 adalah implementasi murni Dart. Anda dapat menghapus konfigurasi yang terkait dengan SDK native dalam proyek Anda, seperti dependensi HTTPDNS di build.gradle dan dependensi AlicloudHTTPDNS di podspec.
2. Refaktor kode inisialisasi
Sebelum peningkatan (1.x)
// 1.x: Inisialisasi dua tahap
await AliyunHttpdns.init(
accountId: Your 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();Setelah peningkatan (2.0)
final config = AliyunHttpdnsConfig(
accountId: Your 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);Catatan:
Semua konfigurasi fitur digabungkan ke dalam parameter konstruktor
AliyunHttpdnsConfig.Anda tidak perlu lagi memanggil metode
build().Parameter konfigurasi baru seperti
region,timeout, dandiscardExpiredAfterSecondsditambahkan.
3. Perbarui API resolusi
Sebelum peningkatan (1.x)
final res = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: 'both',
);
final ipv4s = res['ipv4'] ?? [];
final ipv6s = res['ipv6'] ?? [];Setelah peningkatan (2.0)
final result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: HttpdnsIpType.auto,
);
final ipv4s = result?.ips ?? [];
final ipv6s = result?.ipv6s ?? [];Catatan:
ipTypediubah dari string menjadi enumerasiHttpdnsIpType(auto, v4, v6, both).Nilai kembali diubah dari
Map<String, List<String>>menjadi objekResolveResult?.Nama bidang diubah dari
ipv4/ipv6menjadiips/ipv6s.Dua metode resolusi baru,
resolveHostSyncdanresolveHostAsync, ditambahkan.
4. Perbarui API pre-resolusi
Sebelum peningkatan (1.x)
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com']);Setelah peningkatan (2.0)
await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com']);5. Tambahkan penangan log kustom
AliyunHttpdns.setLogHandler((message) {
print(message);
});6. Perbarui API bersihkan cache
Sebelum peningkatan (1.x)
await AliyunHttpdns.cleanAllHostCache();Setelah peningkatan (2.0)
// Bersihkan semua cache
await AliyunHttpdns.cleanHostCache(null);
// Bersihkan cache untuk nama domain tertentu (baru)
await AliyunHttpdns.cleanHostCache(['www.aliyun.com']);Jika aplikasi Anda tidak menggunakan API yang diubah, Anda tidak perlu melakukan tindakan apa pun.
Tabel pemetaan peningkatan API (1.x → 2.0)
Kategori API | 1.x | 2.0 |
Inisialisasi |
|
|
Aktifkan permintaan HTTPS |
|
|
Aktifkan IP kedaluwarsa |
|
|
Aktifkan cache lokal |
|
|
Pre-resolve saat jaringan berubah |
|
|
IP pilihan |
|
|
Layanan Build |
| Tidak diperlukan |
Resolusi sinkron non-blocking |
|
|
Resolusi sinkron blocking | Tidak ada |
|
Resolusi callback asinkron | Tidak ada |
|
Nilai kembali |
|
|
Tetapkan host pre-resolve |
|
|
Bersihkan cache |
|
|
TTL kustom | Tidak ada |
|
Parameter global SDNS | Tidak ada |
|
Penangan log kustom | Tidak ada |
|
Waktu tanda tangan yang valid | Tidak ada |
|
6.2 Panduan peningkatan dari versi 0.x ke 1.0.0
Versi 1.0.0 memperkenalkan refaktor arsitektur komprehensif dan optimasi API. Peningkatan ini bertujuan untuk:
Menyatukan pola konfigurasi: Beralih dari konfigurasi runtime yang tersebar ke pola inisialisasi dua tahap (init + build). Ini menyelesaikan masalah waktu konfigurasi dan meningkatkan stabilitas SDK.
Menstandarisasi API resolusi: Mendesain ulang arsitektur API resolusi untuk menyediakan metode terpadu
resolveHostSyncNonBlocking. Metode ini mengembalikan data terstruktur, bukan string JSON.Desain dengan metode statis: Beralih dari pola singleton ke pemanggilan metode statis. Ini menyederhanakan penggunaan dan menghilangkan kebutuhan untuk membuat instans.
Mengoptimalkan performa: Meningkatkan performa resolusi dan efisiensi pemanfaatan resource melalui optimasi API dan peningkatan implementasi internal.
Ini adalah perubahan besar yang tidak kompatibel mundur. Meskipun perubahannya signifikan, Anda hanya perlu memodifikasi API yang digunakan aplikasi Anda. Langkah-langkah peningkatan berikut dan tabel pemetaan API lama ke baru dapat membantu Anda menyelesaikan peningkatan penting ini secara sistematis.
Langkah-langkah peningkatan detail
1. Perbarui versi dependensi
pubspec.yaml
dependencies:aliyun_httpdns: ^1.0.0Jalankan pembaruan:
flutter pub upgrade aliyun_httpdns2. Refaktor kode inisialisasi
Sebelum peningkatan
// Versi lama: Pola singleton + inisialisasi satu tahap
final _aliyunHttpDns = AliyunHttpDns();
await _aliyunHttpDns.init(
"YOUR_ACCOUNT_ID", // Tipe 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"]
);Setelah peningkatan
// Versi baru: Metode statis + inisialisasi dua tahap
// Tahap 1: Inisialisasi konfigurasi dasar
await AliyunHttpdns.init(
accountId: your_account_id, // tipe int, wajib
secretKey: "your_secret_key", // Opsional
aesSecretKey: "your_aes_key", // Opsional
);
// Tahap 2: Atur opsi fitur
await AliyunHttpdns.setHttpsRequestEnabled(true); // Menggantikan enableHttps
await AliyunHttpdns.setLogEnabled(true); // Menggantikan enableLog
await AliyunHttpdns.setPersistentCacheIPEnabled(true); // Menggantikan enableCacheIp
await AliyunHttpdns.setReuseExpiredIPEnabled(true); // Menggantikan enableExpireIp
await AliyunHttpdns.setPreResolveAfterNetworkChanged(true); // Menggantikan preResolveAfterNetworkChanged
// Tahap 3: Bangun layanan (harus dipanggil)
await AliyunHttpdns.build();Catatan:
Parameter
region,timeout,enableDegradationLocalDns,ipRankingMap,sdnsGlobalParam, danbizTagstelah dihapus.Metode baru
build()telah ditambahkan. Metode ini harus dipanggil setelah konfigurasi selesai.Semua metode sekarang bersifat statis. Anda tidak perlu membuat instans.
3. Perbarui API resolusi
Sebelum peningkatan
// Sinkron non-blocking, mengembalikan string JSON
String result = await _aliyunHttpDns.resolve(
"YOUR_ACCOUNT_ID", // accountId
"www.aliyun.com", // host
kRequestIpv4AndIpv6, // requestIpType
);
// Memerlukan parsing JSON manual
Map<String, dynamic> map = json.decode(result);
List<String> ipv4s = List<String>.from(map['ipv4'] ?? []);
List<String> ipv6s = List<String>.from(map['ipv6'] ?? []);
// Gunakan IP pertama
String ip = ipv4s.isNotEmpty ? ipv4s.first : '';Setelah peningkatan
// Sinkron non-blocking, mengembalikan data terstruktur
Map<String, List<String>> result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com', // hostname (accountId tidak diperlukan)
ipType: 'both', // Menggantikan kRequestIpv4AndIpv6
);
// Dapatkan daftar IP secara langsung
List<String> ipv4s = result['ipv4'] ?? [];
List<String> ipv6s = result['ipv6'] ?? [];
// Gunakan IP pertama
String ip = ipv4s.isNotEmpty ? ipv4s.first : '';Parameter resolusi kustom:
// Sebelum peningkatan
String result = await _aliyunHttpDns.resolve(
"YOUR_ACCOUNT_ID",
"www.aliyun.com",
kRequestIpv4AndIpv6,
params: {"key": "value"},
cacheKey: "custom_key"
);
// Setelah peningkatan
Map<String, List<String>> result = await AliyunHttpdns.resolveHostSyncNonBlocking(
'www.aliyun.com',
ipType: 'both',
sdnsParams: {"key": "value"}, // Nama parameter diubah
cacheKey: "custom_key"
);4. Perbarui API pre-resolusi
Sebelum peningkatan
await _aliyunHttpDns.setPreResolveHosts(
"YOUR_ACCOUNT_ID", // accountId
["www.aliyun.com"],
kRequestIpv4AndIpv6 // requestIpType
);Setelah peningkatan
await AliyunHttpdns.setPreResolveHosts(
["www.aliyun.com"], // accountId tidak diperlukan
ipType: 'both' // Menggantikan kRequestIpv4AndIpv6
);5. Perbarui konfigurasi log
Sebelum peningkatan
await _aliyunHttpDns.enableLog(true);Setelah peningkatan
await AliyunHttpdns.setLogEnabled(true);6. Perbarui pengambilan SessionId
Sebelum peningkatan
String sessionId = await _aliyunHttpDns.getSessionId("YOUR_ACCOUNT_ID");Setelah peningkatan
String? sessionId = await AliyunHttpdns.getSessionId();7. Gunakan fitur baru
Bersihkan cache
await AliyunHttpdns.cleanAllHostCache();Konfigurasi cache persisten
await AliyunHttpdns.setPersistentCacheIPEnabled(true);Jika aplikasi Anda tidak menggunakan API yang tidak kompatibel, Anda tidak perlu melakukan tindakan apa pun.
Tabel pemetaan peningkatan API
Kategori API | Sebelum peningkatan | Setelah peningkatan |
Buat instans |
| Tidak diperlukan. Gunakan metode statis langsung. |
Inisialisasi |
|
|
Build Service | Tidak ada |
|
Aktifkan permintaan HTTPS |
|
|
Aktifkan IP kedaluwarsa |
|
|
Aktifkan cache lokal |
|
|
Pre-resolve saat jaringan berubah |
|
|
Kontrol output log |
|
|
Resolusi sinkron non-blocking |
|
|
Resolusi IPv4 |
|
|
Resolusi IPv6 |
|
|
Resolusi IPv4 dan IPv6 |
|
|
Pemilihan otomatis | Tidak ada |
|
Parameter resolusi kustom |
|
|
Tetapkan host pre-resolve |
|
|
Dapatkan SessionId |
|
|
Bersihkan cache | Tidak ada |
|
Waktu tanda tangan yang valid |
| Dihapus |