使用 Azure 前端 API 進行驗證
在本節中,我們將描述如何使用 API 來進行驗證和工作階段管理。
警告
本章所述的函數會在內部發出伺服器上的 REST 呼叫。 針對 REST 呼叫,太過頻繁地傳送這些命令也將導致伺服器節流,並在最後傳回失敗。 SessionGeneralContext.HttpResponseCode
成員的值,在此情況下為 429 (「要求太多」)。 根據經驗法則,後續的呼叫之間應該會有 5-10 秒的延遲。
有些函數也會在可放心重試時傳回資訊。 例如,RenderingSessionPropertiesResult.MinimumRetryDelay
指定在嘗試另一次檢查之前所等候的秒數。 可用時,最好使用這類傳回值,因為可讓您盡可能頻繁執行檢查,而不會受到節流。
SessionConfiguration
SessionConfiguration 用來針對 SDK 中的 RemoteRenderingClient
執行個體設定驗證資訊。
重要欄位如下:
public class SessionConfiguration
{
// Domain that will be used for account authentication for the Azure Remote Rendering service, in the form [region].mixedreality.azure.com.
// [region] should be set to the domain of the Azure Remote Rendering account.
public string AccountDomain;
// Domain that will be used to generate sessions for the Azure Remote Rendering service, in the form [region].mixedreality.azure.com.
// [region] should be selected based on the region closest to the user. For example, westus2.mixedreality.azure.com or westeurope.mixedreality.azure.com.
public string RemoteRenderingDomain;
// Can use one of:
// 1) ID and Key.
// 2) ID and AuthenticationToken.
// 3) ID and AccessToken.
public string AccountId = Guid.Empty.ToString();
public string AccountKey = string.Empty;
public string AuthenticationToken = string.Empty;
public string AccessToken = string.Empty;
}
C++ 對應項目如下所示:
struct SessionConfiguration
{
std::string AccountDomain{};
std::string RemoteRenderingDomain{};
std::string AccountId{};
std::string AccountKey{};
std::string AuthenticationToken{};
std::string AccessToken{};
};
針對網域中的區域部分,使用您附近的區域。
您可以從入口網站取得帳戶資訊,如擷取帳戶資訊段落中所述。
Azure Frontend
相關的類別為 RemoteRenderingClient
和 RenderingSession
。 RemoteRenderingClient
用於帳戶管理和帳戶層級功能,其中包括:資產轉換和轉譯工作階段建立。 RenderingSession
用於工作階段層級功能,其中包括:工作階段更新、查詢、更新和解除委任。
每個已開啟/已建立 RenderingSession
都會保留對於前端 (建立工作階段) 的參考。 若要完全關閉,必須先解除配置所有工作階段,然後才會解除配置前端。
解除配置工作階段將不會停止 Azure 上的伺服器,必須明確地呼叫 RenderingSession.StopAsync
。
一旦建立工作階段且其狀態已標示為就緒,就可以使用 RenderingSession.ConnectAsync
連線到遠端轉譯執行階段。
執行緒
所有 RenderingSession 和 RemoteRenderingClient 非同步呼叫都是在背景執行緒中完成,而不是主要應用程式執行緒。
轉換 API
如需轉換服務的詳細資訊,請參閱模型轉換 REST API。
開始資產轉換
async void StartAssetConversion(RemoteRenderingClient client, string storageContainer, string blobinputpath, string bloboutpath, string modelName, string outputName)
{
var result = await client.StartAssetConversionAsync(
new AssetConversionInputOptions(storageContainer, blobinputpath, "", modelName),
new AssetConversionOutputOptions(storageContainer, bloboutpath, "", outputName)
);
}
void StartAssetConversion(ApiHandle<RemoteRenderingClient> client, std::string storageContainer, std::string blobinputpath, std::string bloboutpath, std::string modelName, std::string outputName)
{
AssetConversionInputOptions input;
input.BlobContainerInformation.BlobContainerName = blobinputpath;
input.BlobContainerInformation.StorageAccountName = storageContainer;
input.BlobContainerInformation.FolderPath = "";
input.InputAssetPath = modelName;
AssetConversionOutputOptions output;
output.BlobContainerInformation.BlobContainerName = blobinputpath;
output.BlobContainerInformation.StorageAccountName = storageContainer;
output.BlobContainerInformation.FolderPath = "";
output.OutputAssetPath = outputName;
client->StartAssetConversionAsync(input, output, [](Status status, ApiHandle<AssetConversionResult> result) {
if (status == Status::OK)
{
//use result
}
else
{
printf("Failed to start asset conversion!");
}
});
}
取得轉換狀態
async void GetConversionStatus(RemoteRenderingClient client, string assetId)
{
AssetConversionStatusResult status = await client.GetAssetConversionStatusAsync(assetId);
// do something with status (e.g. check current status etc.)
}
void GetConversionStatus(ApiHandle<RemoteRenderingClient> client, std::string assetId)
{
client->GetAssetConversionStatusAsync(assetId, [](Status status, ApiHandle<AssetConversionStatusResult> result) {
if (status == Status::OK)
{
// do something with result (e.g. check current status etc.)
}
else
{
printf("Failed to get status of asset conversion!");
}
});
}
轉譯 API
如需工作階段管理的詳細資訊,請參閱工作階段管理 REST API。
您可以在服務上動態建立轉譯工作階段,或已經存在的工作階段識別碼可以「開啟」至 RenderingSession 物件。
建立轉譯工作階段
async void CreateRenderingSession(RemoteRenderingClient client, RenderingSessionVmSize vmSize, int maxLeaseInMinutes)
{
CreateRenderingSessionResult result = await client.CreateNewRenderingSessionAsync(
new RenderingSessionCreationOptions(vmSize, maxLeaseInMinutes / 60, maxLeaseInMinutes % 60));
// if the call was successful, result.Session holds a valid session reference, otherwise check result.Context for error information
}
void CreateRenderingSession(ApiHandle<RemoteRenderingClient> client, RenderingSessionVmSize vmSize, int maxLeaseInMinutes)
{
RenderingSessionCreationOptions params;
params.MaxLeaseInMinutes = maxLeaseInMinutes;
params.Size = vmSize;
client->CreateNewRenderingSessionAsync(params, [](Status status, ApiHandle<CreateRenderingSessionResult> result) {
if (status == Status::OK && result->GetErrorCode() == Result::Success)
{
result->GetSession();
//use res->Result
}
else
{
printf("Failed to create session!");
}
});
}
開啟現有的轉譯工作階段
開啟現有的工作階段是同步呼叫。
async void CreateRenderingSession(RemoteRenderingClient client, string sessionId)
{
CreateRenderingSessionResult result = await client.OpenRenderingSessionAsync(sessionId);
if (result.ErrorCode == Result.Success)
{
RenderingSession session = result.Session;
// Query session status, etc.
}
}
void CreateRenderingSession(ApiHandle<RemoteRenderingClient> client, std::string sessionId)
{
client->OpenRenderingSessionAsync(sessionId, [](Status status, ApiHandle<CreateRenderingSessionResult> result) {
if (status == Status::OK && result->GetErrorCode()==Result::Success)
{
ApiHandle<RenderingSession> session = result->GetSession();
// Query session status, etc.
}
});
}
取得目前的轉譯工作階段
async void GetCurrentRenderingSessions(RemoteRenderingClient client)
{
RenderingSessionPropertiesArrayResult result = await client.GetCurrentRenderingSessionsAsync();
if (result.ErrorCode == Result.Success)
{
RenderingSessionProperties[] properties = result.SessionProperties;
// Query session status, etc.
}
}
void GetCurrentRenderingSessions(ApiHandle<RemoteRenderingClient> client)
{
client->GetCurrentRenderingSessionsAsync([](Status status, ApiHandle<RenderingSessionPropertiesArrayResult> result) {
if (status == Status::OK && result->GetErrorCode() == Result::Success)
{
std::vector<RenderingSessionProperties> properties;
result->GetSessionProperties(properties);
}
else
{
printf("Failed to get current rendering sessions!");
}
});
}
工作階段 API
取得轉譯工作階段屬性
async void GetRenderingSessionProperties(RenderingSession session)
{
RenderingSessionPropertiesResult result = await session.GetPropertiesAsync();
if (result.ErrorCode == Result.Success)
{
RenderingSessionProperties properties = result.SessionProperties;
}
else
{
Console.WriteLine("Failed to get properties of session!");
}
}
void GetRenderingSessionProperties(ApiHandle<RenderingSession> session)
{
session->GetPropertiesAsync([](Status status, ApiHandle<RenderingSessionPropertiesResult> result) {
if (status == Status::OK && result->GetErrorCode() == Result::Success)
{
RenderingSessionProperties properties = result->GetSessionProperties();
}
else
{
printf("Failed to get properties of session!");
}
});
}
更新轉譯工作階段
async void UpdateRenderingSession(RenderingSession session, int updatedLeaseInMinutes)
{
SessionContextResult result = await session.RenewAsync(
new RenderingSessionUpdateOptions(updatedLeaseInMinutes / 60, updatedLeaseInMinutes % 60));
if (result.ErrorCode == Result.Success)
{
Console.WriteLine("Rendering session renewed succeeded!");
}
else
{
Console.WriteLine("Failed to renew rendering session!");
}
}
void UpdateRenderingSession(ApiHandle<RenderingSession> session, int updatedLeaseInMinutes)
{
RenderingSessionUpdateOptions params;
params.MaxLeaseInMinutes = updatedLeaseInMinutes;
session->RenewAsync(params, [](Status status, ApiHandle<SessionContextResult> result) {
if (status == Status::OK && result->GetErrorCode() == Result::Success)
{
printf("Rendering session renewed succeeded!");
}
else
{
printf("Failed to renew rendering session!");
}
});
}
停止轉譯工作階段
async void StopRenderingSession(RenderingSession session)
{
SessionContextResult result = await session.StopAsync();
if (result.ErrorCode == Result.Success)
{
Console.WriteLine("Rendering session stopped successfully!");
}
else
{
Console.WriteLine("Failed to stop rendering session!");
}
}
void StopRenderingSession(ApiHandle<RenderingSession> session)
{
session->StopAsync([](Status status, ApiHandle<SessionContextResult> result) {
if (status == Status::OK && result->GetErrorCode() == Result::Success)
{
printf("Rendering session stopped successfully!");
}
else
{
printf("Failed to stop rendering session!");
}
});
}
連線到 ARR 偵測器
async void ConnectToArrInspector(RenderingSession session)
{
string htmlPath = await session.ConnectToArrInspectorAsync();
#if WINDOWS_UWP
UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
{
var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(htmlPath);
await Windows.System.Launcher.LaunchFileAsync(file);
}, true);
#else
InvokeOnAppThreadAsync(() =>
{
System.Diagnostics.Process.Start("file:///" + htmlPath);
});
#endif
}
void ConnectToArrInspector(ApiHandle<RenderingSession> session)
{
session->ConnectToArrInspectorAsync([](Status status, std::string result) {
if (status == Status::OK)
{
// Launch the html file with default browser
std::string htmlPath = "file:///" + result;
ShellExecuteA(NULL, "open", htmlPath.c_str(), NULL, NULL, SW_SHOWDEFAULT);
}
else
{
printf("Failed to connect to ARR inspector!");
}
});
}