本文介紹如何在Unity應用開發中整合使用HTTPDNS。
Unity是即時3D互動內容創作和營運平台。包括遊戲開發、美術、建築、汽車設計、影視在內的所有創作者,藉助Unity將創意變成現實。Unity平台提供一整套完善的軟體解決方案,可用於創作、營運和變現任何即時互動的2D和3D內容,支援平台包括手機、平板電腦、PC、遊戲主機、增強現實和虛擬現實裝置。
隨著使用Unity開發的行動裝置 App越來越多,應用類型越來越廣泛,我們專門提供了針對Unity的HTTPDNS外掛程式,方便Unity開發人員以熟悉方式接入HTTPDNS功能。
以下是外掛程式的使用說明和最佳實務:
一、快速入門
1.1 開通服務
請參考快速入門開通HTTPDNS。
1.2 擷取配置
請參考開發配置在EMAS控制台開發配置中擷取AccountId/SecretKey/AESSecretKey等資訊,用於初始化SDK。
1.3 整合外掛程式到專案
本外掛程式以源碼形式提供,發行到GitHub,需要將外掛程式複製到您的Unity專案中進行整合。
1.3.1 匯入Unity Package
下載本專案的
httpdns_unity_demo目錄將整個
Assets/Plugins目錄複寫到您的Unity專案中將
Assets/Editor目錄(可選,用於建立測試UI)複製到您的專案中
專案結構應如下所示:
YourUnityProject/
├── Assets/
│ ├── Plugins/
│ │ ├── HttpDnsHelper.cs # 主介面檔案
│ │ ├── AndroidHttpDnsHelper.cs # Android平台實現
│ │ ├── iOSHttpDnsHelper.cs # iOS平台實現
│ │ ├── CHttpDnsHelper.cs # C SDK平台實現
│ │ ├── Android/ # Android JAR庫
│ │ ├── iOS/ # iOS Bridge檔案
│ │ └── C/ # C SDK
│ └── Editor/ # 測試UI建立器
├── ProjectSettings/
└── ...外掛程式使用了baseProjectTemplate, mainTemplate, proguard-user, settingsTemplate等檔案,如果專案有其他地方也需要定製這些檔案,請注意合并修改內容。
1.3.2 驗證原生SDK版本
外掛程式已整合了對應平台的HTTPDNS原生SDK,目前的版本:
Android:
com.aliyun.ams:alicloud-android-httpdns:2.6.5iOS:
AlicloudHTTPDNS:3.2.1C:
alibabacloud-httpdns-c-sdk:2.2.5
二、安裝配置
2.1 添加Unity依賴
在您的Unity專案中進行以下配置:
# Unity專案配置
Player Settings:
- Android:
Minimum API Level: 19+
Internet Permission: Enabled
- iOS:
Deployment Target: 12.0+
Internet Capability: Enabled
- C:
Platforms: Windows/macOS
Architectures: x64/arm64
Scripting Backend: Mono 或 IL2CPP外掛程式使用本地源碼依賴方式引用。添加到專案之後需要根據目標平台進行相應配置。
2.2 原生SDK版本更新
如需更新HTTPDNS原生SDK版本,請按以下步驟操作:
2.2.1 更新Android SDK版本
Android 端通過 Maven 依賴管理。請在 Assets/Plugins/Android/mainTemplate.gradle 的 dependencies 中修改版本號碼:
dependencies {
// 其他依賴...
implementation 'com.aliyun.ams:alicloud-android-httpdns:2.6.5' // 修改為所需版本
}提示:Android、iOS、C 三端介面能力存在差異,請以各平台官方介面文檔為準。
啟用了自訂 Gradle 模板(Custom Main/Base Gradle Template、Custom Proguard)後,Unity 構建會自動從倉庫拉取對應版本。
可用版本請參考:Android SDK發布說明
2.2.2 更新iOS SDK版本
編輯構建後處理器中的CocoaPods依賴版本:
// 在 HttpDnsIOSPostProcessor.cs 中更新版本
podfileContent += " pod 'AlicloudHTTPDNS', '~> 3.2.1'\n";
// 更新為您需要的版本
podfileContent += " pod 'AlicloudHTTPDNS', '~> 新版本號碼'\n";可用版本請參考:iOS SDK發布說明
2.2.3 更新C SDK版本
請參考以下步驟操作:
擷取更新後的 C SDK 源碼。
在原生編譯產生原生庫檔案。
將產生的庫檔案放入 Unity 工程的外掛程式目錄,例如
Assets/Plugins/C/x86_64/下的.dll或 macOS 的.dylib。回到 Unity,重新構建專案以生效。
更多資訊與版本說明參考:C SDK發布說明
2.2.4 重新構建專案
更新版本後,需要重新構建專案:
Android:
# Unity Editor中
File -> Build Settings -> Android -> BuildiOS:
# Unity Editor中構建後cd [iOS構建目錄]
pod install --repo-update
open Unity-iPhone.xcworkspaceC (Windows/macOS) :
# Unity Editor中
File -> Build Settings -> PC, Mac & Linux Standalone -> Build三、配置和使用
3.1 初始化配置
應用啟動後,需要先初始化外掛程式,才能調用HTTPDNS能力。 初始化主要是配置AccountId/SecretKey等資訊及功能開關。 範例程式碼如下:
using UnityEngine;
public class HttpDnsManager : MonoBehaviour
{
void Start()
{
// 初始化HTTPDNS - 分階段初始化模式
HttpDnsHelper.init("YOUR_ACCOUNT_ID", "YOUR_SECRET_KEY");
// 設定功能選項
HttpDnsHelper.setHttpsRequestEnabled(true);
HttpDnsHelper.debug(true);
HttpDnsHelper.setTimeout(3000);
// 進階功能配置
HttpDnsHelper.setPersistentCacheIPEnabled(true, 3600); // 啟用持久化緩衝1小時
HttpDnsHelper.setReuseExpiredIPEnabled(true); // 允許複用到期IP
HttpDnsHelper.setPreResolveAfterNetworkChanged(true); // 網路切換時自動預解析
// 構建服務執行個體
bool success = HttpDnsHelper.build();
if (success)
{
Debug.Log("HTTPDNS初始化成功");
// 預解析常用網域名稱
var hosts = new List<string> { "www.aliyun.com", "ecs.console.alibabacloud.com" };
HttpDnsHelper.setPreResolveHosts(hosts, "auto");
}
else
{
Debug.LogError("HTTPDNS初始化失敗");
}
}
}setHttpsRequestEnabled參數設定為true後,計費會增加,請仔細閱讀產品計費文檔。
如果您對網域名稱資訊或SDNS參數有更高的安全訴求,可以配置aesSecretKey參數啟用對解析請求進行內容層加密,使用內容加密後計費會增加,請仔細閱讀產品計費文檔。
3.1.1 日誌配置
應用開發過程中,如果要輸出HTTPDNS的日誌,可以調用日誌輸出控制方法,開啟日誌,範例程式碼如下:
HttpDnsHelper.debug(true);
Debug.Log("日誌輸出已啟用");3.1.2 sessionId記錄
應用在運行過程中,可以調用擷取SessionId方法擷取sessionId,記錄到應用的資料擷取系統中。 sessionId用於表示標識一次應用運行,線上排查時,可以用於查詢應用一次運行過程中的解析日誌,範例程式碼如下:
string sessionId = HttpDnsHelper.getSessionId();
Debug.Log($"SessionId = {sessionId}");3.2 網域名稱解析
3.2.1 預解析
當需要提前解析網域名稱時,可以調用預解析網域名稱方法,範例程式碼如下:
var hosts = new List<string> { "www.aliyun.com", "www.example.com" };
HttpDnsHelper.setPreResolveHosts(hosts, "both");
Debug.Log("預解析設定成功");調用之後,外掛程式會發起網域名稱解析,並把結果緩衝到記憶體,用於後續請求時直接使用。
3.2.2 網域名稱解析
當需要解析網域名稱時,可以通過調用網域名稱解析方法解析網域名稱擷取IP,範例程式碼如下:
public void ResolveDomain(string hostname)
{
// 同步非阻塞解析
var result = HttpDnsHelper.resolveHostSyncNonBlocking(hostname, "auto");
if (result != null)
{
Debug.Log($"IPv4地址: {result.IPv4.Count}個");
Debug.Log($"IPv6地址: {result.IPv6.Count}個");
Debug.Log($"TTL: {result.TTL}秒");
}
}注意:resolveHostSyncNonBlocking 為同步非阻塞解析,可能返回空或無結果。建議配合預解析功能,在無解析結果時回退到系統 DNS 發起請求。
四、Unity最佳實務
4.1 原理說明
本樣本展示了Unity中整合HTTPDNS的完整解決方案:
跨平台統一介面: 使用
HttpDnsHelper提供統一的API介面平台特定實現: 針對Android、iOS、C SDK提供不同的底層實現
自動DNS替換: 在網路請求前自動將網域名稱替換為解析的IP地址
Host頭設定: 確保HTTPS/SSL串連的SNI正確性
4.2 網路請求整合
當使用不同的網路模組發送請求時,需要相應地進行要求標頭配置等操作,下面對HttpClient、HttpWebRequest、UnityWebRequest三種類型分別給出樣本:
4.2.1 HttpClient
using System;
using System.Net.Http;
using UnityEngine;
public class HttpDnsHttpClient : 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 = HttpDnsHelper.resolveHostSyncNonBlocking(hostname, "auto");
if (result != null && result.IPv4 != null && result.IPv4.Count > 0)
{
string resolvedIP = result.IPv4[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 HttpDnsWebRequest : MonoBehaviour
{
public void MakeRequest(string url)
{
try
{
var uri = new Uri(url);
string hostname = uri.Host;
// 使用HTTPDNS解析網域名稱
var result = HttpDnsHelper.resolveHostSyncNonBlocking(hostname, "auto");
if (result != null && result.IPv4 != null && result.IPv4.Count > 0)
{
string resolvedIP = result.IPv4[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 HttpDnsUnityWebRequest : MonoBehaviour
{
public IEnumerator MakeRequest(string url)
{
var uri = new Uri(url);
string hostname = uri.Host;
// 使用HTTPDNS解析網域名稱
var result = HttpDnsHelper.resolveHostSyncNonBlocking(hostname, "auto");
if (result != null && result.IPv4 != null && result.IPv4.Count > 0)
{
string resolvedIP = result.IPv4[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}");
}
}
}
}
}4.3 測試UI使用
專案提供了兩個測試UI建立器:
基礎測試UI: 通過菜單
HttpDNS/Create DNS Test UI建立進階測試UI: 通過菜單
HttpDNS/Create Advanced Test UI建立
測試UI包含完整的功能示範,協助您快速驗證整合效果。
五、API參考
5.1 初始化方法
init
初始化HTTPDNS服務。
// 基礎初始化
HttpDnsHelper.init(string accountId, string secretKey);
// 完整初始化
HttpDnsHelper.init(string accountId, string secretKey, string aesSecretKey);參數說明:
accountId: HTTPDNS賬戶ID(必選)secretKey: 存取金鑰(可選,用於鑒權)aesSecretKey: AES加密金鑰(可選,用於加密)
如果您對網域名稱資訊或SDNS參數有更高的安全訴求,可以配置aesSecretKey參數啟用對解析請求進行內容層加密,使用內容加密後計費會增加,請仔細閱讀產品計費文檔。
build
構建HTTPDNS服務執行個體,在設定完所有配置後調用。
bool success = HttpDnsHelper.build();傳回值:
true: 構建成功false: 構建失敗
5.2 配置方法
debug
控制是否列印調試日誌。
HttpDnsHelper.debug(bool enable);setHttpsRequestEnabled
設定是否使用HTTPS進行DNS查詢。
HttpDnsHelper.setHttpsRequestEnabled(bool enable);setHttpsRequestEnabled參數設定為true後,計費會增加,請仔細閱讀產品計費文檔。
setTimeout
設定DNS查詢逾時時間。
HttpDnsHelper.setTimeout(int timeoutMs);setPersistentCacheIPEnabled
設定是否啟用持久化緩衝。
HttpDnsHelper.setPersistentCacheIPEnabled(bool enable, int cacheTTL);參數:
enable: 是否啟用cacheTTL: 緩衝TTL時間(秒)
setReuseExpiredIPEnabled
設定是否允許複用到期IP。
HttpDnsHelper.setReuseExpiredIPEnabled(bool enable);setPreResolveAfterNetworkChanged
設定網路切換時是否自動重新整理預解析。
HttpDnsHelper.setPreResolveAfterNetworkChanged(bool enable);5.3 解析方法
getIpsByHostAsync
非同步解析網域名稱。
List<string> ips = HttpDnsHelper.getIpsByHostAsync(string hostname);返回:IP地址清單,如果解析失敗返回null或空列表。
getIpsByHost
同步解析網域名稱。
List<string> ips = HttpDnsHelper.getIpsByHost(string hostname);resolveHostSyncNonBlocking
同步非阻塞解析,返回詳細資料。
HttpDnsResult result = HttpDnsHelper.resolveHostSyncNonBlocking(string hostname, string ipType);參數:
hostname: 要解析的網域名稱ipType: IP類型 (“auto”, “ipv4”, “ipv6”, “both”)
返回對象包含:
IPv4: IPv4地址清單IPv6: IPv6地址清單TTL: 緩衝存活時間Extra: 額外資訊
5.4 預解析方法
setPreResolveHosts
設定預解析網域名稱列表。
// 單個網域名稱
HttpDnsHelper.setPreResolveHosts(string hostname);
// 多個網域名稱
HttpDnsHelper.setPreResolveHosts(List<string> hostnames, string ipType);5.5 緩衝管理
clearCache
清除指定網域名稱的緩衝。
HttpDnsHelper.clearCache();cleanAllHostCache
清除所有網域名稱緩衝。
HttpDnsHelper.cleanAllHostCache();5.6 輔助方法
getSessionId
擷取當前會話ID。
string sessionId = HttpDnsHelper.getSessionId();六、常見問題
6.1 Android構建問題
問題: Gradle 無法解析 com.aliyun.ams:alicloud-android-httpdns 依賴或構建失敗。
解決:
啟用自訂 Gradle 模板(Player Settings -> Publishing Settings -> Custom Main/Base Gradle Template)。
檢查
Assets/Plugins/Android/mainTemplate.gradle:repositories是否配置了阿里雲遠程倉庫鏡像。dependencies中存在implementation 'com.aliyun.ams:alicloud-android-httpdns:版本號碼'。
6.2 iOS構建問題
問題: iOS構建後找不到CocoaPods依賴。
解決: 確保按照構建說明執行 pod install 命令,並使用 .xcworkspace 檔案開啟專案。
6.3 C SDK平台問題
問題: C SDK平台缺少原生庫依賴。
解決:
Windows: 確保安裝了VCPKG並設定了環境變數
macOS: 確保安裝了Homebrew依賴庫
檢查構建後處理器是否正確複製了庫檔案
手動複製依賴庫到構建目錄
6.4 網路請求問題
問題: HTTPS請求失敗,提示認證錯誤。
解決: 確保設定了正確的Host頭,使用原始網域名稱而不是IP地址作為SNI。