استخدام 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 الأمامية

الفئات ذات الصلة هي RemoteRenderingClient و RenderingSession. RemoteRenderingClient يستخدم لإدارة الحساب ووظائف مستوى الحساب، والتي تتضمن: تحويل الأصول وإنشاء جلسة العرض. RenderingSession يستخدم لوظائف مستوى جلسة العمل ويتضمن: تحديث الجلسة والاستعلامات والتجديد وإيقاف التشغيل.

سيحتفظ كل فتح/إنشاء RenderingSession بمرجع إلى الواجهة الأمامية التي تم إنشاؤها. لإيقاف التشغيل بشكل نظيف، يجب إلغاء تخصيص جميع الجلسات قبل إلغاء تخصيص الواجهة الأمامية.

لن يؤدي إلغاء تخصيص جلسة عمل إلى إيقاف الخادم على Azure، RenderingSession.StopAsync يجب استدعاؤه بشكل صريح.

بمجرد إنشاء جلسة عمل ووضع علامة على حالتها على أنها جاهزة، يمكنها الاتصال بوقت تشغيل العرض عن بعد باستخدام RenderingSession.ConnectAsync.

خيوط

يتم إكمال كافة استدعاءات RenderingSession وRedyRenderingClient غير المتزامنة في مؤشر ترابط الخلفية، وليس مؤشر ترابط التطبيق الرئيسي.

تحويل واجهات برمجة التطبيقات

لمزيد من المعلومات حول خدمة التحويل، راجع واجهة برمجة تطبيقات 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!");
        }
    });
}

الخطوات التالية