全部產品
Search
文件中心

Alibaba Cloud DNS:Unity接入移動解析HTTPDNS SDK最佳方案

更新時間:Dec 04, 2025

本文檔介紹了Unity情境下的接入移動解析HTTPDNS的方案。

一、概述

Unity是內容創作引擎。Unity可以開發:2D/3D遊戲,2D/3D應用,VR,AR,甚至移動App,網頁前端 ,電影即時渲染等,創作者可以藉助Unity將創意變成現實。

為方便 Unity 開發人員接入使用移動解析HTTPDNS SDK,我們提供了針對Unity情境下的PdnsUnityDemo源碼供使用者參考,源碼中提供了移動解析HTTPDNS Unity外掛程式。

重要

PdnsUnityDemo使用的是Unity 2019.4.21f1c1開發版本,Assets/Plugins目錄下為外掛程式(使用者也可根據實際情況使用阿里雲DNS SDK來製作外掛程式),外掛程式使用了定製的Gradle檔案和Proguard檔案,如果您的專案有其他地方也定製了這些檔案,將內容合并即可。

二、整合方式

  1. 匯入Plugins檔案。

將PdnsUnityDemo中 Plugins 檔案夾中的檔案複製到您 Unity 工程>Assets>Plugins 檔案夾中。

  1. 配置參數。

AlipdnsHelper.setAccountIdAndSetAccessKeyIdAndSetAccesskeySecret("accountId","accessKeyId","accesskeySecret");
AlipdnsHelper.setCacheEnable(true);
AlipdnsHelper.setSchedulePrefetchEnable(true);
AlipdnsHelper.setIspEnable(true);
AlipdnsHelper.setMaxCacheTTL(3600);
AlipdnsHelper.setMaxNegativeCache(60);
AlipdnsHelper.setScheme(1);
AlipdnsHelper.setShortEnable(false);
AlipdnsHelper.setSpeedTestEnable(true);
AlipdnsHelper.setCacheCountLimit(100);
AlipdnsHelper.setSpeedPort(80);
// 預解析網域名稱
List<string> list = new List<string>();
list.Add("網域名稱1");
list.Add("網域名稱2");
AlipdnsHelper.setPreloadDomains(list);

三、API介紹

介面類為AlipdnsHelper.cs。

  1. 必傳參數,accountId,您在控制台註冊後,控制台會產生唯一標識Account ID。

  2. 必傳參數,accessKeyId,accessKeySecret 在控制台開啟鑒權後產生該參數,設定鑒權功能來保障使用者身份安全,不被第三方未授權者盜用。

public static void setAccountIdAndSetAccessKeyIdAndSetAccesskeySecret(string accountId,string accessKeyId,string accessKeySecret)
  1. 設定開啟緩衝,在第一次解析過網域名稱後,後續再解析時, 優先擷取緩衝中的資料,可大大提高解析速度。

public static void setCacheEnable(bool enable)
  1. 設定是否開啟定時主動更新到期緩衝,開啟後SDK每分鐘會自動更新到期緩衝,保障使用者快取資料及時更新,但是可能會帶來網域名稱解析次數和用戶端流量消耗的增多。

public static void setSchedulePrefetchEnable(bool enable)
  1. 設定是否開啟依據ISP網路區分網域名稱緩衝,開啟後則在不同網路環境下網域名稱快取資料分別儲存互不影響。如果不開啟,則在不同網路下使用同一份網域名稱快取資料。

public static void setIspEnable(bool enable)
  1. 設定緩衝最大TTL時間,如果設定了該時間,則會限制緩衝的最大TTL不超過該設定時間。

    SDK預設該參數為3600s。

public static void setMaxCacheTTL(double maxCacheTTL)
  1. 設定否定緩衝最大TTL時間,設定了該時間,則會限制否定緩衝的最大TTL不超過該設定時間。

    SDK預設該參數為30s。

public static void setMaxNegativeCache(double maxNegativeCache)
  1. 在訪問DNS伺服器進行解析時,是通過HTTP協議解析,還是通過HTTPS協議解析,可通過scheme屬性進行設定。scheme預設是0,使用HTTP協議進行解析,建議使用HTTP協議進行解析,解析速度更快,scheme設為1即使用HTTPS協議進行解析。

public static void setScheme(int scheme)
  1. 設定是否開啟short模式,移動解析HTTPDNS的DoH JSON API返回資料分為全量JSON和簡要IP數組格式。SDK預設為全量JSON格式。

public static void setShortEnable(bool enable)
  1. 設定是否開啟IP優選,開啟後解析結果數組會按照測速結果由快到慢的順序排列。

public static void setSpeedTestEnable(bool enable)
  1. 設定緩衝數量,可以自訂緩衝數量(支援範圍100~500之間)。

public static void setCacheCountLimit(int cacheCountLimit)
  1. 設定IP測速優選連接埠,設定socket探測指定連接埠。

public static void setSpeedPort(int speedPort)
  1. 由於SDK內建緩衝功能,在第一次解析完網域名稱後,後續再次解析此網域名稱可大大提高解析速度,所以建議在app啟動後,可對app中可能要解析的網域名稱進行預先載入。

public static void setPreloadDomains(List<string> hosts)
  1. 自動感知網路環境(ipv4-only、ipv6-only、ipv4和ipv6雙棧)直接從緩衝中擷取適用於當前網路環境的IP數組,無需等待。如無緩衝,或有緩衝但已到期並且expiredIPEnabled為false,則返回空。

@param host 網域名稱

@param expiredIPEnabled 是否允許返回到期ip

public static List<string> getIpsByCacheWithDomain(string host, bool expiredIPEnabled)
  1. 直接從緩衝中擷取ipv4解析結果,無需等待. 如無緩衝,或有緩衝但已到期,並且expiredIPEnabled為false,則返回空。

@param host 網域名稱

@param expiredIPEnabled 是否允許返回到期ip

public static List<string> getIpv4ByCacheWithDomain(string host, bool expiredIPEnabled)
  1. 直接從緩衝中擷取ipv6解析結果,無需等待. 如無緩衝,或有緩衝但已到期,並且expiredIPEnabled為false,則返回空。

@param host 網域名稱

@param expiredIPEnabled 是否允許返回到期ip

public static List<string> getIpv6ByCacheWithDomain(string host, bool expiredIPEnabled)
  1. 擷取請求移動解析HTTPDNS成功失敗統計資訊。

public static string getRequestReportInfo()

四、最佳實務

4.1 原理說明

本樣本展示了Unity中整合HTTPDNS的完整解決方案:

  1. 跨平台統一介面:使用 AlipdnsHelper 提供統一的API介面

  2. 平台特定實現:針對 iOS、Android、 SDK提供不同的底層實現

  3. 自動DNS替換:在網路請求前自動將網域名稱替換為解析的IP地址

  4. Host頭設定:確保HTTPS/SSL串連的SNI正確性

4.2 網路請求整合

當使用不同的網路模組發送請求時,需要相應地進行要求標頭配置等操作,下面對HttpClient、HttpWebRequest、UnityWebRequest三種類型分別給出樣本:

4.2.1 HttpClient

using System;
using System.Net.Http;
using UnityEngine;

public class AlipdnsHttpClient : MonoBehaviour
{
    private static readonly HttpClient httpClient = new HttpClient();
    
    public async void MakeRequest(string url)
    {
        try
        {
            var uri = new Uri(url);
            string hostname = uri.Host;
            
            // 使用HTTPDNS解析網域名稱
	    var result = AlipdnsHelper.getIpsByCacheWithDomain(host, true);
            if (result != null && result.Count > 0)
            {
                string resolvedIP = result[0];
                string newUrl = url.Replace(hostname, resolvedIP);
                
                using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, newUrl))
                {
                    // 關鍵:設定Host頭保證SSL/SNI正確性
                    requestMessage.Headers.Host = hostname;
                    
                    var response = await httpClient.SendAsync(requestMessage);
                    string content = await response.Content.ReadAsStringAsync();
                    
                    Debug.Log($"請求成功: {response.StatusCode}");
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"請求失敗: {e.Message}");
        }
    }
}

4.2.2 HttpWebRequest

using System;
using System.IO;
using System.Net;
using UnityEngine;

public class AlipdnsWebRequest : MonoBehaviour
{
    public void MakeRequest(string url)
    {
        try
        {
            var uri = new Uri(url);
            string hostname = uri.Host;
            
            // 使用HTTPDNS解析網域名稱
            var result = AlipdnsHelper.getIpsByCacheWithDomain(host, true);
            if (result != null && result.Count > 0)
            {
                string resolvedIP = result[0];
                string newUrl = url.Replace(hostname, resolvedIP);
                
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(newUrl);
                request.Method = "GET";
                // 關鍵:設定Host頭保證SSL/SNI正確性
                request.Host = hostname;
                
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using (Stream stream = response.GetResponseStream())
                using (StreamReader reader = new StreamReader(stream))
                {
                    string content = reader.ReadToEnd();
                    Debug.Log($"請求成功: {response.StatusCode}");
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"請求失敗: {e.Message}");
        }
    }
}

4.2.3 UnityWebRequest(不推薦)

重要

由於UnityWebRequest無法正確配置SNI(伺服器網域名稱指示)資訊,當伺服器依賴SNI返回特定網域名稱認證時,會導致SSL驗證失敗。因此處理這類網域名稱時,推薦使用前兩種網路請求方式。

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class AlipdnsUnityWebRequest : MonoBehaviour
{
    public IEnumerator MakeRequest(string url)
    {
        var uri = new Uri(url);
        string hostname = uri.Host;
        
        // 使用HTTPDNS解析網域名稱
        var result = AlipdnsHelper.getIpsByCacheWithDomain(host, true);
        if (result != null && result.Count > 0)
        {
            string resolvedIP = result[0];
            string newUrl = url.Replace(hostname, resolvedIP);
            
            using (UnityWebRequest request = UnityWebRequest.Get(newUrl))
            {
                // 關鍵:設定Host頭
                request.SetRequestHeader("Host", hostname);
                
                yield return request.SendWebRequest();
                
                if (request.result == UnityWebRequest.Result.Success)
                {
                    Debug.Log($"請求成功: {request.responseCode}");
                }
                else
                {
                    Debug.LogError($"請求失敗: {request.error}");
                }
            }
        }
    }
}

說明
  1. 當前文檔只針對Unity情境下移動解析HTTPDNS Android/iOS SDK的使用。

  2. 關於移動解析HTTPDNS Android/iOS SDK的接入與使用問題,請查看Android SDK開發指南iOS SDK開發指南

  3. 開發人員在Unity情境下接入移動解析HTTPDNS Android/iOS SDK實踐完整代碼請參考PdnsUnityDemo源碼