All Products
Search
Document Center

HTTPDNS:Integrasikan Flutter SDK

Last Updated:Mar 05, 2026

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 http

Setelah menambahkan dependensi, jalankan flutter pub get.

Catatan

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);
Penting
  • 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:

  1. Buat adapter klien HTTP kustom untuk mengintersepsi permintaan jaringan.

  2. Dalam adapter tersebut, panggil plugin HTTPDNS untuk melakukan resolusi nama domain ke alamat IP.

  3. Gunakan alamat IP yang telah diresolusi untuk membuat koneksi socket langsung.

  4. 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.

Penting

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.0

Jalankan pembaruan:

flutter pub upgrade aliyun_httpdns
Catatan

Versi 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, dan discardExpiredAfterSeconds ditambahkan.

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:

  • ipType diubah dari string menjadi enumerasi HttpdnsIpType (auto, v4, v6, both).

  • Nilai kembali diubah dari Map<String, List<String>> menjadi objek ResolveResult?.

  • Nama bidang diubah dari ipv4/ipv6 menjadi ips/ipv6s.

  • Dua metode resolusi baru, resolveHostSync dan resolveHostAsync, 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']);
Catatan

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

init(accountId:, secretKey:) + berbagai metode set + build()

init(AliyunHttpdnsConfig(...))

Aktifkan permintaan HTTPS

setHttpsRequestEnabled(true)

AliyunHttpdnsConfig(httpsEnabled: true)

Aktifkan IP kedaluwarsa

setReuseExpiredIPEnabled(true)

AliyunHttpdnsConfig(reuseExpiredIPEnabled: true)

Aktifkan cache lokal

setPersistentCacheIPEnabled(true)

AliyunHttpdnsConfig(persistentCacheEnabled: true)

Pre-resolve saat jaringan berubah

setPreResolveAfterNetworkChanged(true)

AliyunHttpdnsConfig(preResolveAfterNetworkChanged: true)

IP pilihan

setIPRankingList({...})

AliyunHttpdnsConfig(ipRankingDatasource: {...})

Layanan Build

build()

Tidak diperlukan

Resolusi sinkron non-blocking

resolveHostSyncNonBlocking(..., ipType: 'both')

resolveHostSyncNonBlocking(..., ipType: HttpdnsIpType.both)

Resolusi sinkron blocking

Tidak ada

resolveHostSync(...) (baru)

Resolusi callback asinkron

Tidak ada

resolveHostAsync(..., callback: ...) (baru)

Nilai kembali

Map<String, List<String>> (res['ipv4'])

ResolveResult? (result?.ips)

Tetapkan host pre-resolve

setPreResolveHosts(..., ipType: 'both')

setPreResolveHosts(..., ipType: HttpdnsIpType.both)

Bersihkan cache

cleanAllHostCache()

cleanHostCache(List<String>?)

TTL kustom

Tidak ada

setTtlChanger(...) (baru)

Parameter global SDNS

Tidak ada

setSdnsGlobalParams({...}) (baru)

Penangan log kustom

Tidak ada

setLogHandler(...) (baru)

Waktu tanda tangan yang valid

Tidak ada

setAuthCurrentTime(int) (baru)

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.0

Jalankan pembaruan:

flutter pub upgrade aliyun_httpdns
2. 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, dan bizTags telah 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);
Catatan

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

AliyunHttpDns()

Tidak diperlukan. Gunakan metode statis langsung.

Inisialisasi

init(String accountId, {...})

init({required int accountId, ...})

Build Service

Tidak ada

build() (Baru, harus dipanggil)

Aktifkan permintaan HTTPS

init(enableHttps: true)

setHttpsRequestEnabled(true)

Aktifkan IP kedaluwarsa

init(enableExpireIp: true)

setReuseExpiredIPEnabled(true)

Aktifkan cache lokal

init(enableCacheIp: true)

setPersistentCacheIPEnabled(true)

Pre-resolve saat jaringan berubah

init(preResolveAfterNetworkChanged: true)

setPreResolveAfterNetworkChanged(true)

Kontrol output log

enableLog(bool)

setLogEnabled(bool)

Resolusi sinkron non-blocking

resolve(String accountId, String host, String requestIpType)

resolveHostSyncNonBlocking(String hostname, {String ipType})

Resolusi IPv4

resolve(..., kRequestIpv4)

resolveHostSyncNonBlocking(..., ipType: 'ipv4')

Resolusi IPv6

resolve(..., kRequestIpv6)

resolveHostSyncNonBlocking(..., ipType: 'ipv6')

Resolusi IPv4 dan IPv6

resolve(..., kRequestIpv4AndIpv6)

resolveHostSyncNonBlocking(..., ipType: 'both')

Pemilihan otomatis

Tidak ada

resolveHostSyncNonBlocking(..., ipType: 'auto')

Parameter resolusi kustom

resolve(..., params: {...})

resolveHostSyncNonBlocking(..., sdnsParams: {...})

Tetapkan host pre-resolve

setPreResolveHosts(String accountId, List<String>, String requestIpType)

setPreResolveHosts(List<String>, {String ipType})

Dapatkan SessionId

getSessionId(String accountId)

getSessionId()

Bersihkan cache

Tidak ada

cleanAllHostCache()

Waktu tanda tangan yang valid

setAuthCurrentTime(String accountId, int)

Dihapus