文档

C SDK接入

更新时间:

本章节介绍了HTTPDNS C SDK的接入方法。

环境准备

SDK的集成依赖于必要的构建工具和第三方库,在集成SDK前请在构建机器上安装这些依赖。

名称

描述

版本

git

版本控制工具

1.8及以上

cmake

构建工具

3.0及以上

gcc

编译工具

4.5及以上

vcpkg(可选)

依赖库管理工具

推荐最新版本

libcurl

应用层协议库

7.33.0及以上

apr/apr-util

C\C++跨平台组件库

1.5.2及以上

cjson

JSON字符串解析

推荐最新版本

构建工具安装

构建过程中需要使用git克隆代码、使用cmake构建工程、使用gcc/g++编译代码,请您确认这些命令行工具已经安装在本机,如果尚未安装,请参考以下命令安装:

  • Ubuntu/Debian

    sudo  apt update
    sudo  apt install -y git cmake gcc g++
  • Aliyun/CentOS Stream/Fedora

    sudo yum check-update
    sudo yum install -y git cmake  gcc  gcc-c++
  • OpenSUSE

    sudo zypper refresh
    sudo zypper install -y git cmake  gcc  gcc-c++
  • macOS

    export HOMEBREW_NO_AUTO_UPDATE=1
    brew install git gcc cmake
    说明

    注意:brew非macOS自带的包管理器,安装包之前请先安装brew

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • Windows

    下载安装Git下载安装Visual Studio (工作负载选择“使用C++的桌面开发”)

依赖库安装

SDK使用libcurl库(版本7.33.0及以上)进行网络操作,使用apr/apr-util(版本1.5.2及以上)库解决内存管理以及跨平台问题,使用cjson库解析服务端响应报文,SDK并没有带上这几个外部库,您需要确认这些库已经安装,并且将它们的头文件目录和库文件目录都加入到了项目中。本项目支持VCPKG安装和手动安装两种方式安装这些C/C++库。

VCPKG安装

  • 安装VCPKG

  • 安装SDK依赖的库

    • macOS/Linux

       ./vcpkg install apr apr-util curl[openssl,http2] cjson
    • Windows

      .\vcpkg.exe install apr apr-util curl[openssl,http2] cjson

手动安装

  • Ubuntu/Debian

    sudo  apt update
    sudo apt install -y libcurl4-openssl-dev libapr1-dev libaprutil1-dev libcjson-dev
  • Aliyun/CentOS Stream/Fedora

    sudo yum check-update
    sudo yum install -y libcurl-devel apr-devel apr-util-devel cjson-devel
  • OpenSUSE

    sudo zypper refresh
    sudo zypper install -y libcurl-devel libapr1-devel libapr-util1-devel cJSON-devel
  • macOS

    brew install curl apr apr-util cjson
  • Windows

    下载安装cjson下载安装openssl下载安装curl下载安装apr/apr-util

说明

注意:如果cJSON开发包不能通过Unix-like平台包管理器自动安装,可以通过以下命令手动安装:

git clone https://github.com/DaveGamble/cJSON.git && cd cJSON && mkdir build && cd build && cmake  ../ && sudo make install && cd ../../ && rm -rf cJSON

SDK安装

  • Linux/macOS

    git clone https://github.com/aliyun/alibabacloud-httpdns-c-sdk.git
    cd alibabacloud-httpdns-c-sdk
    mkdir build
    cd build
    # 如果是通过VCPKG安装的依赖库,则构建SDK时需要添加Cmake参数 -DVCPKG_ROOT=${vcpkg的安装路径}
    cmake -DCMAKE_BUILD_TYPE=Release ../ 
    make hdns_unite_test
    sudo make install
    sudo ldconfig
  • Windows

    • 下载工程

    • Visual Studio打开Cmake工程

    • 管理配置中配置Cmake命令参数:-DVCPKG_ROOT=${vcpkg的安装路径}

SDK集成

SDK的集成可以参考C 集成示例,下面介绍具体集成步骤。

引入SDK

集成SDK需要引入安装在本地的库和头文件,以cmake工程为例,在工程CMakeLists.txt文件中加入以下命令:

find_library(HTTPDNS_LIBRARY httpdns_c_sdk_static)
include_directories(${CMAKE_INSTALL_PREFIX}/include/httpdns)

SDK初始化

SDK运行环境初始化。

 if (hdns_sdk_init() != HDNS_OK) {
        hdns_sdk_cleanup();
  }
   
  // 使用SDK API
  
  

客户端创建

 hdns_client_t *client = hdns_client_create(HTTPDNS_ACCOUNT, HTTPDNS_SECRET);
 if (client == NULL) {
    hdns_sdk_cleanup();
  }
 // 使用HTTPDNS Client
说明
  • HTTPDNS_ACCOUNT是HTTPDNS为账户分配的Account ID,获取方式参考产品使用流程

  • HTTPDNS_SECRET是请求加签时的密钥,如果不需要鉴权,则设置为NULL,如果解析需要鉴权,则需要填入,参考文档鉴权配置

客户端配置

客户端实例创建成功之后,如果用户希望对HTTPDNS 客户端进行自定义配置可以通过以下方式进行:

// 设置请求服务端超时时间,单位:ms
hdns_client_set_timeout(client, 2000);
// 是否开启本地缓存
hdns_client_set_using_cache(client, true);
// 是否使用https协议访问HTTPDNS服务端
hdns_client_set_using_https(client, true);
// 请求是否进行加签
hdns_client_set_using_sign(client,  true);
// 请求服务端重试次数
hdns_client_set_retry_times(client, 1);
// 设置HTTPDNS解析服务集群
hdns_client_set_region(client, "global");
// 设置HTTPDNS调度集群
hdns_client_set_schedule_center_region(client, "cn");
// 设置网络变化后是否更新本地缓存
hdns_client_enable_update_cache_after_net_change(client, true);
// 是否允许获取过期缓存
hdns_client_enable_expired_ip(client, true);
// 是否自动降级到localdns
hdns_client_enable_failover_localdns(client, true);
// 添加预解析域名
hdns_client_add_pre_resolve_host(client, "www.aliyun.com");
// 添加Ip嗅探
hdns_client_add_ip_probe_item(client, "www.aliyun.com", 443);
// 自定义ttl
hdns_client_add_custom_ttl_item(client, "www.aliyun.com", 120);

客户端启动

   hdns_client_start(client);

域名解析

客户端实例启动之后,就可以调用SDK提供的API进行域名解析了,SDK针对不同的场景提供了多个API接口,这里以单域名同步接口为例,展示调用API获取HTTPDNS解析结果的使用过程。

    hdns_list_head_t *results = NULL;
    hdns_status_t status = hdns_get_result_for_host_sync_with_cache(client,
                                                                    MOCK_BUSINESS_HOST,
                                                                    HDNS_QUERY_AUTO,
                                                                    NULL, &results);

IP选择

通过SDK API获取域名的解析结果之后,就可以通过解析的IP访问客户的业务了。

 if (hdns_status_is_ok(&status)) {
        char ip[HDNS_IP_ADDRESS_STRING_LENGTH];
        if (hdns_select_ip_randomly(results, HDNS_QUERY_AUTO, ip) == HDNS_OK) {
            mock_access_business_web_server(ip);
        }
  }
  if (hdns_status_is_ok(&status)) {
        char ip[HDNS_IP_ADDRESS_STRING_LENGTH];
        if (hdns_select_ip_randomly(results, HDNS_QUERY_AUTO, ip) == HDNS_OK) {
            mock_access_business_web_server(ip);
        }
  }
  hdns_list_free(results);

业务访问

static void mock_access_business_web_server(const char *dst_ip) {
    CURL *curl;
    CURLcode res;
    curl = curl_easy_init();
    if (curl) {
        // 拼接业务URL
        char url[256];
        strcpy(url, "https://");
        strcat(url, MOCK_BUSINESS_HOST);
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);

        // HTTPS设置预解析的主机和 IP
        struct curl_slist *dns;
        char sni[256];
        strcpy(sni, MOCK_BUSINESS_HOST);
        strcat(sni, ":443:");
        strcat(sni, dst_ip);
        dns = curl_slist_append(NULL, sni);
        curl_easy_setopt(curl, CURLOPT_RESOLVE, dns);
        // 设置响应结果回调
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data_callback);
#if defined(_WIN32)
        curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
#endif
        // 发起HTTP请求
        res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed, url=%s, ip=%s, error=%s\n",
                    url,
                    dst_ip,
                    curl_easy_strerror(res));
        }
        // 释放业务访问相关资源
        curl_slist_free_all(dns);
        /* always cleanup */
        curl_easy_cleanup(curl);
    }
}

客户端清理

client不再使用后,需要将其释放。

hdns_client_cleanup(client);

SDK清理

SDK不再使用后,需要将其释放。

hdns_sdk_cleanup();