استخدام Azure Frontend APIs للمصادقة
في هذا القسم، سنصف كيفية استخدام واجهة برمجة التطبيقات للمصادقة وإدارة الجلسات.
تنبيه
الوظائف الموضحة في هذا الفصل إصدار REST يستدعي على الخادم داخليا. أما بالنسبة لجميع مكالمات REST ، فإن إرسال هذه الأوامر بشكل متكرر للغاية سيؤدي إلى خنق الخادم وإرجاع الفشل في النهاية. قيمة العضو في SessionGeneralContext.HttpResponseCode هذه الحالة هي 429 ("عدد كبير جدا من الطلبات"). وكقاعدة عامة، يجب أن يكون هناك تأخير من 5-10 ثوانٍ بين المكالمات اللاحقة.
تقوم بعض الوظائف أيضا بإرجاع المعلومات عند حفظها لإعادة المحاولة. على سبيل المثال RenderingSessionPropertiesResult.MinimumRetryDelay ، يحدد عدد الثواني التي يجب انتظارها قبل محاولة إجراء فحص آخر. عند توفرها ، يعد استخدام هذه القيمة المرتجعة هو الأفضل ، لأنه يسمح لك بإجراء عمليات فحص كلما أمكن ذلك ، دون التعرض للخنق.
تكوين الجلسة
يستخدم SessionConfiguration لإعداد معلومات المصادقة لمثيل RemoteRenderingClient في SDK.
المجالات الهامة هي:
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 غير المتزامنة في مؤشر ترابط الخلفية، وليس مؤشر ترابط التطبيق الرئيسي.
واجهات برمجة تطبيقات التحويل
لمزيد من المعلومات حول خدمة التحويل، راجع واجهة برمجة تطبيقات REST لتحويل النموذج.
بدء تحويل مواد العرض
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!");
}
});
}
عرض واجهات برمجة التطبيقات
راجع واجهة برمجة تطبيقات REST لإدارة الجلسات للحصول على تفاصيل حول إدارة الجلسات.
يمكن إنشاء جلسة عرض إما ديناميكيا على الخدمة أو يمكن "فتح" معرف جلسة عمل موجود بالفعل في كائن 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!");
}
});
}
واجهات برمجة تطبيقات الجلسة
الحصول على خصائص جلسة العرض
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!");
}
});
}