Verwenden der Azure-Front-End-APIs für die Authentifizierung
In diesem Abschnitt wird die Verwendung der API für Authentifizierung und Sitzungsverwaltung beschrieben.
Achtung
Die in diesem Kapitel beschriebenen Funktionen geben intern REST-Aufrufe auf dem Server aus. Wie bei allen REST-Aufrufen bewirkt das zu häufige Senden dieser Befehle, dass der Server eine Drosselung durchführt und schließlich einen Fehler zurückgibt. Der Wert des Members SessionGeneralContext.HttpResponseCode
lautet in diesem Fall 429 („Zu viele Anforderungen“). Als Faustregel sollte eine Verzögerung von 5–10 Sekunden zwischen nachfolgenden Aufrufen erfolgen.
Einige Funktionen geben auch Informationen zurück, wenn der Vorgang gefahrlos wiederholt werden kann. RenderingSessionPropertiesResult.MinimumRetryDelay
gibt beispielsweise an, wie viele Sekunden gewartet werden soll, bevor eine weitere Überprüfung versucht wird. Die Verwendung eines solchen Rückgabewerts (falls verfügbar) ist die beste Option, da Sie dann ohne Drosselung Überprüfungen so oft wie möglich durchführen können.
SessionConfiguration
„SessionConfiguration“ wird verwendet, um die Authentifizierungsinformationen für eine RemoteRenderingClient
-Instanz im SDK einzurichten.
Die wichtigen Felder lauten:
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;
}
Die C++-Entsprechung sieht folgendermaßen aus:
struct SessionConfiguration
{
std::string AccountDomain{};
std::string RemoteRenderingDomain{};
std::string AccountId{};
std::string AccountKey{};
std::string AuthenticationToken{};
std::string AccessToken{};
};
Verwenden Sie für den Teil region in der Domäne eine Region in Ihrer Nähe.
Die Kontoinformationen können aus dem Portal abgerufen werden, wie im Abschnitt Abrufen von Kontoinformationen beschrieben.
Azure-Front-End
Die relevanten Klassen lauten RemoteRenderingClient
und RenderingSession
. RemoteRenderingClient
wird für die Kontoverwaltung und für Funktionalität auf Kontoebene verwendet, einschließlich der Ressourcenkonvertierung und der Erstellung von Renderingsitzungen. RenderingSession
wird für Funktionen auf Sitzungsebene verwendet, einschließlich Sitzungsaktualisierung, Abfragen, Erneuern und Außerbetriebsetzung.
Jede geöffnete/erstellte RenderingSession
verfügt über einen Verweis auf das Front-End, von dem sie erstellt wurde. Zum ordnungsgemäßen Herunterfahren muss die Zuordnung aller Sitzungen aufgehoben werden, bevor die Zuordnung des Front-Ends aufgehoben wird.
Durch Aufheben der Zuordnung einer Sitzung wird der Server in Azure nicht beendet; RenderingSession.StopAsync
muss explizit aufgerufen werden.
Nachdem eine Sitzung erstellt und ihr Status als bereit markiert wurde, kann sie mittels RenderingSession.ConnectAsync
mit der Remote Rendering-Runtime verbunden werden.
Threading
Alle asynchronen RenderingSession- und RemoteRenderingClient-Aufrufe werden in einem Hintergrundthread ausgeführt, nicht im Hauptthread der Anwendung.
Konvertierungs-APIs
Weitere Informationen zum Konvertierungsdienst finden Sie unter Verwenden der REST-API für die Modellkonvertierung.
Startet die Objektkonvertierung.
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!");
}
});
}
Abrufen des Konvertierungsstatus
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!");
}
});
}
Rendering-APIs
Ausführliche Informationen zur Sitzungsverwaltung finden Sie unter REST-API für die Sitzungsverwaltung.
Eine Renderingsitzung kann entweder dynamisch für den Dienst erstellt werden, oder eine Sitzung mit einer bereits vorhandenen Sitzungs-ID kann in einem RenderingSession-Objekt geöffnet werden.
Erstellen einer Renderingsitzung
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!");
}
});
}
Öffnen einer vorhandenen Renderingsitzung
Das Öffnen einer vorhandenen Sitzung ist ein synchroner Aufruf.
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.
}
});
}
Abrufen aktueller Renderingsitzungen
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!");
}
});
}
Sitzungs-APIs
Abrufen von Renderingsitzungseigenschaften
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!");
}
});
}
Aktualisieren einer Renderingsitzung
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!");
}
});
}
Beenden einer Renderingsitzung
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!");
}
});
}
Verbinden mit ARRInspector
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!");
}
});
}