Utiliser les API Azure Frontend pour l’authentification
Cette section décrit comment utiliser l’API pour l’authentification et la gestion des sessions.
Attention
Les fonctions décrites dans ce chapitre émettent des appels REST sur le serveur en interne. Comme pour tous les appels REST, une fréquence trop élevée d’envoi de ces commandes entraîne une limitation du serveur, et finit par retourner un échec. Dans ce cas, la valeur du membre SessionGeneralContext.HttpResponseCode
est 429 (« trop de demandes »). En règle générale, il doit y avoir un délai de 5 à 10 secondes entre les appels successifs.
Certaines fonctions retournent également des informations quand une nouvelle tentative peut être effectuée sans problème. Par exemple, RenderingSessionPropertiesResult.MinimumRetryDelay
spécifie le nombre de secondes à attendre avant de tenter une autre vérification. Si une valeur retournée comme celle-ci est disponible, nous vous recommandons de l’utiliser. Vous pourrez ainsi effectuer autant de vérifications que possible sans aucune limitation.
SessionConfiguration
SessionConfiguration est utilisé pour configurer les informations d’authentification d’une instance RemoteRenderingClient
dans le Kit de développement logiciel (SDK).
Les champs importants sont les suivants :
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;
}
Le compteur C++ équivalent ressemble à ceci :
struct SessionConfiguration
{
std::string AccountDomain{};
std::string RemoteRenderingDomain{};
std::string AccountId{};
std::string AccountKey{};
std::string AuthenticationToken{};
std::string AccessToken{};
};
Pour la partie région du domaine, utilisez une région proche de chez vous.
Les informations de compte peuvent être obtenues à partir du portail, comme décrit dans le paragraphe Récupérer les informations de compte.
Front-end Azure
Les classes pertinentes sont RemoteRenderingClient
et RenderingSession
. RemoteRenderingClient
est utilisé pour la gestion des comptes et les fonctionnalités au niveau du compte, notamment : la conversion des ressources et la création d’une session de rendu. RenderingSession
est utilisé pour les fonctionnalités au niveau de la session et comprend : la mise à jour de la session, les requêtes, le renouvellement et la désaffectation.
Chaque RenderingSession
ouvert/créé conserve une référence au serveur frontal qui l’a créé. Pour les arrêter correctement, toutes les sessions doivent être libérées avant le serveur frontal.
La libération d’une session n’arrête pas le serveur sur Azure, RenderingSession.StopAsync
doit être appelé explicitement.
Une fois qu’une session a été créée et que son état est marqué comme prêt, elle peut se connecter au runtime de rendu distant avec RenderingSession.ConnectAsync
.
Threads
Tous les appels asynchrones RenderingSession et RemoteRenderingClient sont effectués dans un thread d’arrière-plan, et non dans le thread d’application principal.
API de conversion
Pour plus d’informations sur le service de conversion, consultez l’API REST de conversion de modèle.
Lance une conversion de ressources
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!");
}
});
}
Récupère l’état de la 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 de rendu
Pour plus d’informations sur la gestion des sessions, consultez l’API REST de gestion de session.
Une session de rendu peut être créée dynamiquement sur le service ou un ID de session existant peut être « ouvert » dans un objet RenderingSession.
Créer une session de rendu
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!");
}
});
}
Ouvre une session de rendu existante
L’ouverture d’une session existante est un appel synchrone.
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.
}
});
}
Reçoit les sessions de rendu actuelles
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 de session
Obtient les propriétés de la session de rendu
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!");
}
});
}
Met à jour la session de rendu
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!");
}
});
}
Arrête la session de rendu
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!");
}
});
}
Se connecte à l’inspecteur 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!");
}
});
}