Aracılığıyla paylaş


Hızlı Başlangıç: Windows Uygulama SDK'sında anında iletme bildirimleri

Bu hızlı başlangıçta, Windows Uygulama SDK'sınıkullanarak push bildirimleri gönderen ve alan bir Windows masaüstü uygulaması oluşturacaksınız.

Prerequisites

Örnek uygulama

Bu hızlı başlangıçta, Windows Uygulama SDK 1.7'de uygulamanıza anında iletme bildirimleri desteği ekleme adımları gösterilir. GitHub'da bulunan örnek uygulamalarda bu hızlı başlangıçtakine benzer kodlara bakın. Projenize en uygun örnekler için tercih ettiğiniz Windows Uygulama SDK'sı sürümünü içeren dalı gözden geçirmeyi unutmayın.

Ayrıca, örnek deposunda bir sürüm dalı seçerek Windows Uygulama SDK'sının her sürümü için örnekler bulabilirsiniz.

API referansı

Anında iletme bildirimlerine yönelik API başvuru belgeleri için bkz. Microsoft.Windows.PushNotifications Ad Alanı.

Azure Active Directory'de (AAD) uygulamanızın kimliğini yapılandırma

Windows Uygulama SDK'sında anında iletme bildirimleri, Azure Active Directory(AAD) kimliklerini kullanır. WNS Kanal URI'sini istemek ve anında iletme bildirimleri göndermek için erişim belirteçleri istemek için Azure kimlik bilgileri gereklidir. Uyarı: Microsoft İş Ortağı Merkezi ile Windows Uygulama SDK'sı anında iletme bildirimlerini kullanmayı DESTEKLEMİYORUZ.

1. Adım: AAD uygulama kaydı oluşturma

Azure hesabınızda oturum açın ve yeni bir AAD Uygulama Kaydı kaynağı oluşturun. Yeni kayıtseçin.

2. Adım: Bir ad girin ve çok kiracılı bir seçenek belirleyin

  1. Bir uygulama adı belirtin.

  2. Anında iletme bildirimleri çok kiracılı seçeneği gerektirir, bu nedenle bunu seçin.

    1. Kiracılar hakkında daha fazla bilgi için bkz. Uygulamanızda kimler oturum açabilir?.
  3. Kayıt Seç

  4. Uygulama (istemci) kimliğinizinot alın, çünkü bu, etkinleştirme kaydı ve erişim belirteci isteği sırasında kullanacağınız Azure AppId'dür.

  5. Not edin ki bu, erişim belirteci isterken kullanacağınız Azure TenantId olduğundan, Dizin (kiracı) kimliğinizinot alın.

    Important

    AAD Uygulama Kayıt Kiracısı Uygulama (istemci) kimliğinizi ve Dizin (kiracı) kimliğinizinot edin.

  6. Nesne Kimliğinizinot edin. Bu, kanal isteğinde bulunurken kullanacağınız Azure NesneKimliğiniz. Bunun Temel Parçalar sayfasında listelenen nesne kimliği DEĞİlDİĞİNE dikkat edin. Bunun yerine, doğru Nesne Kimliğinibulmak için, Temel Parçalar sayfasındaki yerel dizinindeki Yönetilen uygulama alanında uygulama adına tıklayın.

    Temel Parçalar sayfasındaki Yönetilen uygulama yerel dizin seçeneğini gösteren ekran görüntüsü

    Nesne Kimliği alanını gösteren ekran görüntüsü

    Note

    Nesne Kimliği elde etmek için hizmet sorumlusu gerekir. Uygulamanızla ilişkilendirilmiş bir tane yoksa, Azure portalında veya komut satırını kullanarak aşağıdaki yazılardan birinde yer alan adımları izleyin:

    Kaynaklara erişebilen bir Azure AD uygulaması ve hizmet sorumlusu oluşturmak için portalı kullanın

    Azure PowerShell kullanarak bir sertifika ile hizmet sorumlusu oluşturma

3. Adım: Uygulama kaydınız için bir gizli anahtar oluşturma

Gizli anahtarınız, anında iletme bildirimleri göndermek üzere bir erişim belirteci istediğinizde Azure AppId/ClientId'niz ile birlikte kullanılır.

AAD Uygulama Gizli Anahtarı

Sertifikalar ve sırlar bölümüne gidin ve Yeni istemci sırrı seçin.

Important

Gizli anahtarınızı oluşturduktan sonra kopyaladığınızdan ve Azure Key Vault gibi güvenli bir konumda sakladığınızdan emin olun. Oluşturulduktan hemen sonra yalnızca bir kez görüntülenebilir.

4. Adım: Uygulamanızın Paket Aile Adını Azure AppId'siyle eşleme

Uygulamanız paketlenmişse (dış konumla birlikte dahil), uygulamanızın Paket Aile Adı (PFN) ile Azure AppId'sini eşlemek için bu akışı kullanabilirsiniz.

Uygulamanız paketlenmiş bir Win32 uygulamasıysa "Windows Uygulama SDK'sı Anında İletme Bildirimleri Eşleme İsteği" konu satırını ve "PFN: [PFN'niz]", "AppId: [APPId'niz]", "ObjectId: [ObjectId'niz]" metnini içeren bir e-posta Win_App_SDK_Push@microsoft.com adresine göndererek bir Paket Aile Adı (PFN) eşleme isteği oluşturun. Haritalama istekleri haftalık olarak tamamlanır. Eşleme isteğiniz tamamlandıktan sonra size bildirilir.

Azure AppId, ObjectId ve gizli dizinizi aldıktan sonra bu kimlik bilgilerini aşağıdaki örnek koda ekleyebilirsiniz.

Uygulamanızı anında iletme bildirimleri alacak şekilde yapılandırma

1. Adım: Windows Uygulama SDK'sı ve gerekli NuGet paketlerini ekleme

Ardından Çözüm Gezgini'nde çözüme sağ tıklayın ve NuGet Paketlerini Yönet'i seçin.

Paket Yöneticisi'ne aşağıdaki paketleri ekleyin:

  • Microsoft.WindowsAppSDK (en düşük sürüm 1.1.0)
  • Microsoft.Windows.SDK.BuildTools (en düşük sürüm 10.0.22000.194)
  • Microsoft.Windows.CppWinRT, (en düşük sürüm 2.0.210930.14)
  • Microsoft.Windows.ImplementationLibrary, (en düşük sürüm 1.0.210930.1)

Projenizde Windows Uygulama SDK'sını ilk kez kullanıyorsanız ve dış konumla paketlenmişse veya paketi açılmışsa, proje dosyanıza aşağıdaki özelliği ekleyerek Windows Uygulama SDK'sını başlatın:

<!-- your .vcxproj or .proj file -->
<PropertyGroup Label="Globals">
    <!-- Other properties -->
    <WindowsPackageType>None</WindowsPackageType>
</PropertyGroup>

veya önyükleyici API'sini kullanın. Daha fazla ayrıntı için bkz. Dış konumla paketlenmiş veya paketlenmemiş uygulamalar için Windows Uygulama SDK'sı çalışma zamanını kullanma .

Note

SDK başlatılmazsa uygulama oluşturulur System.Runtime.InteropServices.COMException (0x80040154): Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)) ve çalışmaz.

2. Adım: Ad alanları ekleme

Ardından, Windows Uygulama SDK'sı anında iletme bildirimleri Microsoft.Windows.PushNotificationsiçin ad alanını ekleyin.

#include <winrt/Microsoft.Windows.PushNotifications.h>

using namespace winrt::Microsoft::Windows::PushNotifications;

"Microsoft.Windows.PushNotifications bulunamıyor" hatası alırsanız, bu büyük olasılıkla üst bilgi dosyalarının oluşturulmadığı anlamına gelir. Sorunu çözmek için yukarıdaki paketlerin yüklü olduğundan emin olun, hataya neden olan include ve using deyimlerini açıklama satırı yapıp uygulamayı yeniden oluşturarak üst bilgi dosyalarını oluşturun. Derleme başarılı olduktan sonra include ve using deyimlerini açın ve projeyi yeniden derleyin. Bu, hatayı çözecektir.

3. Adım: COM etkinleştiricinizi uygulamanızın bildirimine ekleme

Important

Uygulamanız paketten çıkarılmışsa (yani çalışma zamanında paket kimliği eksikse), 4. Adım: Uygulama başlatma sırasında anında iletme bildirimlerine kaydolma ve bunlara yanıt verme bölümüne atlayın.

Uygulamanız paketlenmişse (dış bir konumla birlikte paketlenmişse): Package.appxmanifestaçın. <Application> öğesinin içine aşağıdakileri ekleyin. Id, Executableve DisplayName değerlerini uygulamanıza özgü değerlerle değiştirin.

<!--Packaged apps only-->
<!--package.appxmanifest-->

<Package
  ...
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
  ...
  <Applications>
    <Application>
      ...
      <Extensions>

        <!--Register COM activator-->    
        <com:Extension Category="windows.comServer">
          <com:ComServer>
              <com:ExeServer Executable="SampleApp\SampleApp.exe" DisplayName="SampleApp" Arguments="----WindowsAppRuntimePushServer:">
                <com:Class Id="[Your app's Azure AppId]" DisplayName="Windows App SDK Push" />
            </com:ExeServer>
          </com:ComServer>
        </com:Extension>
    
      </Extensions>
    </Application>
  </Applications>
 </Package>    

Note

Bu örnek için tamamlanmış C++ sınıfı örneği 5. Adımdan sonra bulunabilir. 4. ve 5. adımlarda, son örnekteki her bir parçayı eklemek için adım adım yönergeler sağlanır.

4. Adım: Uygulama başlangıcında anında iletme bildirimlerine kaydolma ve bu bildirimlere yanıt verme

Aşağıdakileri eklemek için uygulamanızın main() yöntemini güncelleştirin:

  1. PushNotificationManager::Default().Register()çağrısı yaparak push bildirimleri almak için uygulamanızı kaydedin.
  2. AppInstance::GetCurrent() öğesini çağırarak etkinleştirme isteğinin kaynağını denetleyin. GetActivatedEventArgs(). Başlatma bir anlık bildirimden tetiklendiyse, bildirimin yüküne göre yanıt verin.

Important

PushNotificationManager::Default().Register çağrısını yapmalısınız. Bu işlem, AppInstance.GetCurrent.GetActivatedEventArgsçağrısını yapmadan önce gerçekleştirilmelidir.

Ön plan olay işleyicileri ekleme

Ön planda bir olayı işlemek için PushNotificationManager.PushReceived için bir işleyici kaydedin.

Important

PushNotificationManager.Register() çağrısı yapmadan önce tüm PushNotificationManager.PushReceived olay işleyicilerini de kaydetmeniz gerekir. Aksi takdirde, aşağıdaki çalışma zamanı özel durumu oluşturulur:

System.Runtime.InteropServices.COMException: Element not found. Must register event handlers before calling Register().

PushNotificationManager::IsSupported() denetimini ekleyin

Ardından PushNotification API'lerinin PushNotificationManager.IsSupported() ile desteklenip desteklenmediğini denetleyin. Aksi takdirde yoklama veya kendi özel yuva uygulamanızı kullanmanızı öneririz.

Artık onaylanan anında iletme bildirimi desteği olduğuna göre PushNotificationReceivedEventArgs temelinde davranış ekleyin.

5. Adım: WNS Kanal URI'sini isteme ve WNS sunucusuna kaydetme

WNS Kanal URI'leri anında iletme bildirimleri göndermeye yönelik HTTP uç noktalarıdır. Her istemcinin bir Kanal URI'sini istemesi ve anında iletme bildirimleri almak için bunu WNS sunucusuna kaydetmesi gerekir.

Note

WNS Kanal URI'lerinin süresi 30 gün sonra dolar.

auto channelOperation{ PushNotificationManager::Default().CreateChannelAsync(winrt::guid("[Your app's Azure ObjectID]")) };

Öğretici kodunu takip ediyorsanız Azure Nesne Kimliğinizi buraya ekleyin:

// To obtain an AAD RemoteIdentifier for your app,
// follow the instructions on https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app
winrt::guid remoteId{ "00000000-0000-0000-0000-000000000000" }; // Replace this with your own Azure ObjectId

PushNotificationManager bir Kanal URI'si oluşturmayı dener ve en fazla 15 dakika boyunca otomatik olarak yeniden dener. Çağrının tamamlanmasını beklemek için bir olay işleyicisi oluşturun. Çağrı tamamlandıktan sonra başarılı olursa URI'yi WNS sunucusuna kaydedin.

Örnek Kod

#include <iostream>
#include <winrt/Microsoft.Windows.PushNotifications.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Microsoft.Windows.AppLifecycle.h>
#include <winrt/Windows.ApplicationModel.Background.h>
#include <wil/cppwinrt.h>
#include <wil/result.h>

using namespace winrt::Microsoft::Windows::PushNotifications;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Windows::AppLifecycle;

// To obtain an AAD RemoteIdentifier for your app,
// follow the instructions on https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app
winrt::guid remoteId{ "00000000-0000-0000-0000-000000000000" }; // Replace this with your own Azure ObjectId

winrt::Windows::Foundation::IAsyncOperation<PushNotificationChannel> RequestChannelAsync()
{
    auto channelOperation = PushNotificationManager::Default().CreateChannelAsync(remoteId);

    // Set up the in-progress event handler
    channelOperation.Progress(
        [](auto&& sender, auto&& args)
        {
            if (args.status == PushNotificationChannelStatus::InProgress)
            {
                // This is basically a noop since it isn't really an error state
                std::cout << "Channel request is in progress." << std::endl << std::endl;
            }
            else if (args.status == PushNotificationChannelStatus::InProgressRetry)
            {
                LOG_HR_MSG(
                    args.extendedError,
                    "The channel request is in back-off retry mode because of a retryable error! Expect delays in acquiring it. RetryCount = %d",
                    args.retryCount);
            }
        });

    auto result = co_await channelOperation;

    if (result.Status() == PushNotificationChannelStatus::CompletedSuccess)
    {
        auto channelUri = result.Channel().Uri();

        std::cout << "channelUri: " << winrt::to_string(channelUri.ToString()) << std::endl << std::endl;

        auto channelExpiry = result.Channel().ExpirationTime();

        // Caller's responsibility to keep the channel alive
        co_return result.Channel();
    }
    else if (result.Status() == PushNotificationChannelStatus::CompletedFailure)
    {
        LOG_HR_MSG(result.ExtendedError(), "We hit a critical non-retryable error with channel request!");
        co_return nullptr;
    }
    else
    {
        LOG_HR_MSG(result.ExtendedError(), "Some other failure occurred.");
        co_return nullptr;
    }

};

PushNotificationChannel RequestChannel()
{
    auto task = RequestChannelAsync();
    if (task.wait_for(std::chrono::seconds(300)) != AsyncStatus::Completed)
    {
        task.Cancel();
        return nullptr;
    }

    auto result = task.GetResults();
    return result;
}

void SubscribeForegroundEventHandler()
{
    winrt::event_token token{ PushNotificationManager::Default().PushReceived([](auto const&, PushNotificationReceivedEventArgs const& args)
    {
        auto payload{ args.Payload() };

        std::string payloadString(payload.begin(), payload.end());
        std::cout << "\nPush notification content received in the FOREGROUND: " << payloadString << std::endl;
    }) };

    std::cout << "Push notification foreground event handler registered." << std::endl;
}

int main()
{
    // Set up an event handler, so we can receive notifications in the foreground while the app is running.
    // You must register notification event handlers before calling Register(). Otherwise, the following runtime
    // exception will be thrown: System.Runtime.InteropServices.COMException: 'Element not found. Must register
    // event handlers before calling Register().'
    SubscribeForegroundEventHandler();

    // Register the app for push notifications.
    PushNotificationManager::Default().Register();

    auto args{ AppInstance::GetCurrent().GetActivatedEventArgs() };
    switch (args.Kind())
    {
        case ExtendedActivationKind::Launch:
        {
            std::cout << "App launched by user or from the debugger." << std::endl;
            if (PushNotificationManager::IsSupported())
            {
                std::cout << "Push notifications are supported on this device." << std::endl;

                // Request a WNS Channel URI which can be passed off to an external app to send notifications to.
                // The WNS Channel URI uniquely identifies this app for this user and device.
                PushNotificationChannel channel{ RequestChannel() };
                if (!channel)
                {
                    std::cout << "\nThere was an error obtaining the WNS Channel URI" << std::endl;

                    if (remoteId == winrt::guid{ "00000000-0000-0000-0000-000000000000" })
                    {
                        std::cout << "\nThe ObjectID has not been set. Refer to the readme file accompanying this sample\nfor the instructions on how to obtain and setup an ObjectID" << std::endl;
                    }
                }

                std::cout << "\nPress 'Enter' at any time to exit App." << std::endl;
                std::cin.ignore();
            }
            else
            {
                std::cout << "Push notifications are NOT supported on this device." << std::endl;
                std::cout << "App implements its own custom socket here to receive messages from the cloud since Push APIs are unsupported." << std::endl;
                std::cin.ignore();
            }
        }
        break;

        case ExtendedActivationKind::Push:
        {
            std::cout << "App activated via push notification." << std::endl;
            PushNotificationReceivedEventArgs pushArgs{ args.Data().as<PushNotificationReceivedEventArgs>() };

            // Call GetDeferral to ensure that code runs in low power
            auto deferral{ pushArgs.GetDeferral() };

            auto payload{ pushArgs.Payload() };

            // Do stuff to process the raw notification payload
            std::string payloadString(payload.begin(), payload.end());
            std::cout << "\nPush notification content received in the BACKGROUND: " << payloadString.c_str() << std::endl;
            std::cout << "\nPress 'Enter' to exit the App." << std::endl;

            // Call Complete on the deferral when finished processing the payload.
            // This removes the override that kept the app running even when the system was in a low power mode.

            deferral.Complete();
            std::cin.ignore();
        }
        break;

        default:
            std::cout << "\nUnexpected activation type" << std::endl;
            std::cout << "\nPress 'Enter' to exit the App." << std::endl;
            std::cin.ignore();
            break;
    }
}

6. Adım: Uygulamanızı derleme ve yükleme

Uygulamanızı derlemek ve yüklemek için Visual Studio'yu kullanın. Çözüm Gezgini'nde çözüm dosyasına sağ tıklayın ve Dağıt'ı seçin. Visual Studio uygulamanızı derleyip makinenize yükler. Uygulamayı Başlat Menüsü veya Visual Studio hata ayıklayıcısı aracılığıyla başlatarak çalıştırabilirsiniz.

Öğretici kodunun konsolu şöyle görünür:

çalışan örnek konsol

Uygulamanıza anında iletme bildirimi göndermek için belirteci kullanmanız gerekir.

Uygulamanıza anında iletme bildirimi gönderme

Bu noktada tüm yapılandırma tamamlanır ve WNS sunucusu istemci uygulamalarına anında iletme bildirimleri gönderebilir. Aşağıdaki adımlarda, daha fazla ayrıntı için Anında iletme bildirimi sunucusu isteğine ve yanıt üst bilgilerine bakın.

1. Adım: Erişim belirteci isteme

Anında iletme bildirimi göndermek için WNS sunucusunun önce erişim belirteci istemesi gerekir. Azure TenantId, Azure AppId ve gizli dizinizle bir HTTP POST isteği gönderin. Azure TenantId ve Azure AppId alma hakkında bilgi için bkz. oturum açmak için kiracı ve uygulama kimliği değerlerini alma.

HTTP Örnek İsteği:

POST /{tenantID}/oauth2/v2.0/token Http/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 160

grant_type=client_credentials&client_id=<Azure_App_Registration_AppId_Here>&client_secret=<Azure_App_Registration_Secret_Here>&scope=https://wns.windows.com/.default/

C# Örnek İsteği:

//Sample C# Access token request
var client = new RestClient("https://login.microsoftonline.com/{tenantID}/oauth2/v2.0");
var request = new RestRequest("/token", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("client_id", "[Your app's Azure AppId]");
request.AddParameter("client_secret", "[Your app's secret]");
request.AddParameter("scope", "https://wns.windows.com/.default");
RestResponse response = await client.ExecutePostAsync(request);
Console.WriteLine(response.Content);

İsteğiniz başarılı olursa, access_token alanında belirtecinizi içeren bir yanıt alırsınız.

{
    "token_type":"Bearer",
    "expires_in":"86399",
    "ext_expires_in":"86399",
    "expires_on":"1653771789",
    "not_before":"1653685089",
    "access_token":"[your access token]"
}

Adım 2. Ham bildirim gönderme

Önceki adımda aldığınız erişim belirtecini ve göndermek istediğiniz anında iletme bildiriminin içeriğini içeren bir HTTP POST isteği oluşturun. Anında iletme bildiriminin içeriği uygulamaya teslim edilecek.

POST /?token=[The token query string parameter from your channel URL. E.g. AwYAAABa5cJ3...] HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: application/octet-stream
X-WNS-Type: wns/raw
Authorization: Bearer [your access token]
Content-Length: 46

{ Sync: "Hello from the Contoso App Service" }
var client = new RestClient("[Your channel URL. E.g. https://wns2-by3p.notify.windows.com/?token=AwYAAABa5cJ3...]");
var request = new RestRequest();
request.Method = Method.Post; 
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("X-WNS-Type", "wns/raw");
request.AddHeader("Authorization", "Bearer [your access token]");
request.AddBody("Notification body");
RestResponse response = await client.ExecutePostAsync(request);");

3. Adım: Bulut kaynaklı uygulama bildirimi gönderme

Yalnızca ham bildirimler göndermek istiyorsanız bu adımı göz ardı edin. Anında iletme bildirimi olarak da bilinen bulut kaynaklı bir uygulama bildirimi göndermek için, önce Hızlı Başlangıç: Windows Uygulama SDK'sıuygulama bildirimleri'ni izleyin. Uygulama bildirimleri buluttan ya da yerel olarak gönderilebilir. Bulut kaynaklı uygulama bildirimi göndermek, X-WNS-Type üst bilgisinin olması, toastolması ve içerikte uygulama bildirimi XML yükünün yer aldığı durumlar dışında text/xmlham bildirim göndermeye benzer. XML yükünüzü oluşturma hakkında daha fazla bilgi için bkz. Notifications XML şeması.

Erişim belirtecinizi ve göndermek istediğiniz bulut kaynaklı uygulama bildiriminin içeriğini içeren bir HTTP POST isteği oluşturun. Anında iletme bildiriminin içeriği uygulamaya teslim edilecek.

POST /?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: text/xml
X-WNS-Type: wns/toast
Authorization: Bearer [your access token]
Content-Length: 180

<toast><visual><binding template="ToastGeneric"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>
var client = new RestClient("https://dm3p.notify.windows.com/?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy");
client.Timeout = -1;

var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "text/xml");
request.AddHeader("X-WNS-Type", "wns/toast");
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddParameter("text/xml", "<toast><visual><binding template=\"ToastGeneric\"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>",  ParameterType.RequestBody);
Console.WriteLine(response.Content);

Resources