Harmony SDK开发指南

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

本文档介绍了阿里云公共DNS Harmony SDK的接入和开发方式。

1.如何接入SDK

进入控制台“接入配置”功能下载鸿蒙版SDK,并集成SDK在自己的App工程项目中,您可以参考Demo示例工程源码了解如何使用本SDK。

1.1引用本地HAR包方式集成SDK

在工程的oh-package.json5中设置三方包依赖。以HAR包在工程根目录下为例,配置示例如下(实际配置时请以HAR包实际目录为准):

"dependencies": {
    "alipdnslibrary": "file:alidns-harmony-sdk-1.0.0.har"
 }

依赖设置完成后,需要执行ohpm install命令安装依赖包,依赖包会存储在工程的oh_modules目录下。

ohpm install

1.2 如何使用SDK

  • 引入头文件

import { Alipdns,schemaType,DNSDomainInfo, DNSlogger } from 'alipdnslibrary'
  • 设置鉴权模式

开启鉴权模式,以保障用户身份安全,不被第三方未授权者盗用,用户在Alibity onCreate生命周期回调中执行以下代码配置SDK:

重要

用户请参考创建密钥在控制台创建AccessKey ID 和 AccessKey Secret

import { Alipdns,schemaType,DNSDomainInfo, DNSlogger } from 'alipdnslibrary'

const AccountID = '这里需要替换为设置您在控制台接入SDK的Account ID';
const AccessKeID = '这里需要替换为您在控制台“接入配置”创建的密钥的 AccessKey ID';
const AccessKeySecret = '这里需要替换为您在控制台“接入配置”创建的密钥的 AccessKey Secret';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // ************* 阿里pdns-sdk配置 begin *************
    DNSlogger.setEnableLogger = true;
    let alipdns = Alipdns.getInstance();
    alipdns.Init(this.context,AccountID,AccessKeID,AccessKeySecret);
    alipdns.setKeepAliveDomains(['*****','*****']);
    alipdns.setSchemaType(schemaType.https);
    alipdns.preLoadDomains(alipdns.QTYPE_V4,['*****','*****','*****']);
    // ************* 阿里pdns-sdk配置 end *************
  }

  // 省略其它代码
}

2.API介绍

2.1 Account ID和鉴权

必传参数,您在控制台注册自己的应用后,控制台会为此应用生成唯一标识Account ID,鉴权功能来保障用户身份安全,防止被第三方未授权者盗用。用户请参考创建密钥在控制台创建AccessKey,并在APP中通过如下代码设置:

Alipdns.getInstance().Init(this.context,AccountID,AccessKeID,AccessKeySecret);
警告
  • 为避免在日志中泄漏参数Account ID/AccessKey ID/AccessKey SecretApp运行过程中产生的数据,建议线上版本关闭SDK调试日志。

  • Account ID、AccessKey ID 和 AccessKey Secret此类参数与计量计费密切相关,为防止恶意反编译获取参数造成信息泄露,在生产环境中,您需要避免直接传入明文。例如,您可以预先把明文进行编码或加密处理,在传值的时候再对已编码或加密的明文进行解码或解密。同时,建议您对 app 进行代码混淆处理并加固。否则,您的Account ID、AccessKey ID 和 AccessKey Secret可能会被第三方通过反编译的方式获得。

2.2 解析协议设置

SDK支持设置DNS解析请求协议类型,可自主选择通过HTTPHTTPS协议解析,具体可通过scheme属性进行设置。

SDK默认并推荐使用HTTPS协议进行解析,因为HTTPS协议安全性更好。公共DNS的计费项是按HTTP的解析次数进行收费,其中HTTPS是按5HTTP流量进行计费,开发者可以根据自身实际业务需要选择scheme类型。如下设置:

Alipdns.getInstance().setSchemaType(schemaType.https);

2.3 设置域名缓存保持

SDK在缓存功能已开启的情况下,可设置针对某些域名开启缓存保持功能,如果该功能开启,SDK会自动更新这些域名的过期缓存,保障用户缓存数据及时更新,但是可能会带来域名解析次数和客户端流量消耗的增多。如果不设置该功能,那么SDK不会自动进行过期缓存更新,只有当用户调用解析方法时,才会再次进行缓存更新。若要设置某些域名的缓存保持需要通过以下代码设置:

Alipdns.getInstance().setKeepAliveDomains(['*****','*****']);
说明
  • 优势:

    • 可及时(TTL过期前)更新记录。

    • 配合预加载可降低首次解析延迟(0ms)。

  • 劣势:缓存时间超过TTL*75%之后会再重新请求,会带来额外的费用。

2.4 预解析

由于SDK可以设置开启缓存功能,在第一次解析完域名产生缓存后,后续再次解析此域名时解析速度可提升至0时延。因此,建议在app启动后,对app中可能要解析的域名进行预解析。

代码示例:

Alipdns.getInstance().preLoadDomains(alipdns.QTYPE_V4,['*****','*****','*****']);

2.5 设置开启SDK调试日志开关

用户可以设置是否开启SDK调试日志开关(true为开启调试日志,false为关闭调试日志),该方法请在SDK初始化前设置。

DNSlogger.setEnableLogger = true;

2.6解析方法

SDK提供不同的域名解析方法,示例如下:

/// 异步解析方法
/// Alipdns.getInstance().QTYPE_V4           解析ip地址类型:ipv4
/// host                                     要解析的域名
/// ips                                      回调(所有ip地址)
Alipdns.getInstance().getIpsByHostAsync(Alipdns.getInstance().QTYPE_V4, host,(ips:string[]) => {});

/// 同步解析方法(取缓存中的数据)
/// Alipdns.getInstance().QTYPE_V4           解析ip地址类型:ipv4
/// host                                     要解析的域名
/// true                                     是否允许返回过期ip结果
const result = Alipdns.getInstance().getIpsByHostFromCache(Alipdns.getInstance().QTYPE_V4,host,true);

3.如何使用SDK

addCustomDnsRule方式

在发起网络请求之前,调用SDK的域名解析API进行公共DNS解析,通过connection.addCustomDnsRuleAPI配置公共DNS的解析结果,为当前应用程序添加自定义host和对应的IP地址的映射。以HTTP请求为例,代码如下:

import { http } from '@kit.NetworkKit';
import connection from '@ohos.net.connection';
import { Alipdns,schemaType,DNSDomainInfo } from 'alipdnslibrary'
import Url from '@ohos.url';

export async function requestWithHttpDns(url: string, options: http.HttpRequestOptions): Promise<http.HttpResponse> {
  let urlObject = Url.URL.parseURL(url);
  const host = urlObject.hostname;
  // ************* 公共DNS解析获取域名 begin *************
  const result = Alipdns.getInstance().getIpsByHostFromCache(Alipdns.getInstance().QTYPE_V4,host,true);
  // ************* 公共DNS解析获取域名 end *************
  // ************* 通过系统API设置DNS规则 begin *************
  try {
    await connection.removeCustomDnsRule(host);
  } catch (ignored) {
  }
  if (result.length ?? 0 > 0) {
    await connection.addCustomDnsRule(host, result);
  } else {
    console.log(`httpdns解析没有结果,不设置dns`);
  }
  // ************* 通过系统API设置DNS规则 begin *************
  // ************* 通过系统API进行网络请求 begin *************
  const httpRequest = http.createHttp();
  return httpRequest.request(url, options);
  // ************* 通过系统API进行网络请求 end *************
}
重要

HarmonyOS 如何定制DNS解析规则

HarmonyOS 提供了定制DNS解析规则的API:addCustomDnsRuleremoveCustomDnsRuleclearCustomDnsRules

通过addCustomDnsRule API应用可以添加自定义host和对应的IP地址的映射,

通过removeCustomDnsRule API应用可以删除对应host的自定义DNS规则,

通过clearCustomDnsRules API应用可以删除所有的自定义DNS规则。

因此,当应用想要定制网络请求的DNS规则时,可以在网络请求之前,通过上述API设置对应的规则,然后再发起网络请求。

Remote Communication KitdnsRules方式

当使用Remote Communication Kit包进行网络请求时,可以先调用SDK的域名解析API进行公共DNS解析,然后通过配置dnsRules字段,修改DNS规则,以fetch请求为例,代码如下:

import { Alipdns,schemaType,DNSDomainInfo } from 'alipdnslibrary'
import { rcp } from '@kit.RemoteCommunicationKit';
import Url from '@ohos.url';

export async function rcpWithHttpDns(url: string): Promise<rcp.Response> {
  let urlObject = Url.URL.parseURL(url);
  const host = urlObject.hostname;
  // ************* 公共DNS解析域名获取IP结果 begin *************
  const result = Alipdns.getInstance().getIpsByHostFromCache(Alipdns.getInstance().QTYPE_V4,host,true);
  // ************* 公共DNS解析域名获取IP结果 end *************
  const request = new rcp.Request(url, "GET");
  if (result.length ?? 0 > 0) {
      request.configuration = {
        dns: {
          // ************* 通过dnsRules设置IP begin *************
          dnsRules: [{ host, port: 443, ipAddresses: result },{ host, port: 80, ipAddresses: result }]
          // ************* 通过dnsRules设置IP end *************
        }
      }
    }
  // ************* 通过系统API进行网络请求 begin *************
  const session = rcp.createSession();
  return session.fetch(request);
  // ************* 通过系统API进行网络请求 end *************
}