Samouczek: wysyłanie powiadomień do konkretnych użytkowników przy użyciu usługi Azure Notification Hubs

Omówienie

W tym samouczku opisano sposób wysyłania powiadomień wypychanych do określonego użytkownika aplikacji na określonym urządzeniu przy użyciu usługi Azure Notification Hubs. Zaplecze ASP.NET interfejsu WebAPI jest używane do uwierzytelniania klientów. Kiedy zaplecze uwierzytelnia użytkownika aplikacji klienckiej, automatycznie dodaje tag do rejestracji powiadomienia. Zaplecze używa tego tagu do wysyłania powiadomień do określonego użytkownika.

Uwaga

Ukończony kod dla tego samouczka można znaleźć w witrynie GitHub.

W tym samouczku wykonasz następujące kroki:

  • Tworzenie projektu interfejsu WebAPI
  • Uwierzytelnianie klientów w zapleczu interfejsu WebAPI
  • Rejestrowanie na potrzeby powiadomień za pomocą zaplecza interfejsu WebAPI
  • Wysyłanie powiadomień z zaplecza interfejsu WebAPI
  • Publikowanie nowego zaplecza interfejsu WebAPI
  • Aktualizowanie kodu na potrzeby projektu klienta
  • Testowanie aplikacji

Wymagania wstępne

Ten samouczek jest oparty na centrum powiadomień i projekcie programu Visual Studio, które zostały utworzone w samouczku Samouczek: wysyłanie powiadomień do aplikacji platformy uniwersalnej systemu Windows przy użyciu usługi Azure Notification Hubs. W związku z tym należy zakończyć powyższy samouczek przed rozpoczęciem tego samouczka.

Uwaga

Jeśli używasz usługi Mobile Apps w usłudze Azure App Service jako usługi zaplecza, zobacz sekcję Wersja usługi Mobile Apps niniejszego samouczka.

Tworzenie projektu interfejsu WebAPI

W poniższych sekcjach omówiono proces tworzenia nowego zaplecza interfejsu WebAPI platformy ASP.NET. Ten proces ma trzy główne cele:

  • Uwierzytelnianie klientów: procedura obsługi komunikatów jest dodawana w celu uwierzytelnienia żądań klientów i kojarzenia użytkownika z żądaniem.
  • Rejestrowanie do używania powiadomień za pomocą zaplecza interfejsu WebAPI: kontroler jest dodawany w celu obsługi nowych rejestracji, aby urządzenie klienckie mogło otrzymywać powiadomienia. Nazwa uwierzytelnionego użytkownika jest automatycznie dodawana do rejestracji jako tag.
  • Wysyłanie powiadomień do klientów: jest dodawany kontroler udostępniający użytkownikom możliwość wyzwalania bezpiecznej operacji wypychania do urządzeń i klientów skojarzonych z tagiem.

Utwórz nowe zaplecze internetowego interfejsu API ASP.NET Core 6.0, wykonując następujące czynności:

Aby to sprawdzić, uruchom program Visual Studio. W menu Narzędzia wybierz pozycję Rozszerzenia i aktualizacje. Wyszukaj pozycję Menedżer pakietów NuGet w swojej wersji programu Visual Studio i sprawdź, czy masz najnowszą wersję. Jeśli nie używasz najnowszej wersji, odinstaluj ją i ponownie zainstaluj Menedżera pakietów NuGet.

Zrzut ekranu przedstawiający okno dialogowe Rozszerzenia i Aktualizacje z wyróżnionym pakietem NuGet Dla programu Visual Studios.

Uwaga

Upewnij się, że zainstalowano zestaw Azure SDK programu Visual Studio na potrzeby wdrażania witryny internetowej.

  1. Uruchom program Visual Studio lub Visual Studio Express.

  2. Wybierz pozycję Eksplorator serwera i zaloguj się do konta platformy Azure. Aby tworzyć zasoby witryny internetowej na swoim koncie, musisz się zalogować.

  3. W menu Plik programu Visual Studio wybierz pozycję Nowy>projekt.

  4. Wprowadź internetowy interfejs API w polu wyszukiwania.

  5. Wybierz szablon projektu internetowego interfejsu API ASP.NET Core i wybierz przycisk Dalej.

  6. W oknie dialogowym Konfigurowanie nowego projektu nadaj projektowi nazwę AppBackend i wybierz pozycję Dalej.

  7. W oknie dialogowym Dodatkowe informacje :

    • Upewnij się, że platforma.NET 6.0 (obsługa długoterminowa).
    • Upewnij się, że pole wyboru Użyj kontrolerów (usuń zaznaczenie, aby używać minimalnych interfejsów API) jest zaznaczone.
    • Usuń zaznaczenie pola wyboru Włącz obsługę interfejsu OpenAPI.
    • Wybierz przycisk Utwórz.

Usuwanie plików szablonów WeatherForecast

  1. Usuń przykładowe pliki WeatherForecast.cs i Controllers/WeatherForecastController.cs z nowego projektu AppBackend .
  2. Otwórz plik Properties\launchSettings.json.
  3. Zmień właściwości launchUrl z weatherforcast na appbackend.

W oknie Konfigurowanie aplikacji internetowej platformy Microsoft Azure wybierz subskrypcję, a następnie na liście Plan usługi App Service wykonaj jedną z następujących akcji:

  • Wybierz plan Azure App Service, który został już utworzony.
  • Wybierz pozycję Utwórz nowy plan usługi App Service, a następnie utwórz plan.

Ten samouczek nie wymaga bazy danych. Po wybraniu planu usługi App Service kliknij przycisk OK, aby utworzyć projekt.

Okno Konfigurowanie aplikacji internetowej platformy Microsoft Azure

Jeśli nie widzisz tej strony na potrzeby konfigurowania planu usługi App Service, przejdź do samouczka. Można ją skonfigurować podczas publikowania aplikacji później.

Uwierzytelnianie klientów w zapleczu interfejsu WebAPI

W tej sekcji tworzysz nową klasę procedury obsługi komunikatów o nazwie AuthenticationTestHandler dla nowego zaplecza. Ta klasa pochodzi od klasy DelegatingHandler i jest dodawana jako procedura obsługi komunikatów, aby umożliwić przetwarzanie wszystkich żądań przychodzących do zaplecza.

  1. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt AppBackend, wybierz polecenie Dodaj, a następnie wybierz pozycję Klasa.

  2. Nadaj nowej klasie nazwę AuthenticationTestHandler.cs, a następnie wybierz pozycję Dodaj, aby wygenerować klasę. Ta klasa służy do uwierzytelniania użytkowników za pomocą Uwierzytelniania podstawowego dla uproszczenia. Twoja aplikacja może używać dowolnego schematu uwierzytelniania.

  3. W klasie AuthenticationTestHandler.cs dodaj następujące instrukcje using:

    using System.Net.Http;
    using System.Threading;
    using System.Security.Principal;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
  4. W klasie AuthenticationTestHandler.cs zastąp definicję klasy AuthenticationTestHandler następującym kodem:

    Ta procedura obsługi autoryzuje żądanie, gdy następujące trzy warunki zostaną spełnione:

    • Żądanie zawiera nagłówek Authorization.
    • Żądanie używa uwierzytelniania basic.
    • Ciąg nazwy użytkownika i ciąg hasła to ten sam ciąg.

    W przeciwnym razie żądanie jest odrzucane. To uwierzytelnianie nie reprezentuje rzeczywistego podejścia do uwierzytelniania i autoryzacji. Jest to wyłącznie prosty przykład na potrzeby tego samouczka.

    Jeśli komunikat żądania jest uwierzytelniany i autoryzowany przez klasę AuthenticationTestHandler, użytkownik uwierzytelniania podstawowego jest dołączany do bieżącego żądania w obiekcie HttpContext. Informacje o użytkowniku w obiekcie HttpContext zostaną później użyte przez inny kontroler (RegisterController) w celu dodania tagu do żądania rejestracji powiadomienia.

    public class AuthenticationTestHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var authorizationHeader = request.Headers.GetValues("Authorization").First();
    
            if (authorizationHeader != null && authorizationHeader
                .StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
            {
                string authorizationUserAndPwdBase64 =
                    authorizationHeader.Substring("Basic ".Length);
                string authorizationUserAndPwd = Encoding.Default
                    .GetString(Convert.FromBase64String(authorizationUserAndPwdBase64));
                string user = authorizationUserAndPwd.Split(':')[0];
                string password = authorizationUserAndPwd.Split(':')[1];
    
                if (VerifyUserAndPwd(user, password))
                {
                    // Attach the new principal object to the current HttpContext object
                    HttpContext.Current.User =
                        new GenericPrincipal(new GenericIdentity(user), new string[0]);
                    System.Threading.Thread.CurrentPrincipal =
                        System.Web.HttpContext.Current.User;
                }
                else return Unauthorized();
            }
            else return Unauthorized();
    
            return base.SendAsync(request, cancellationToken);
        }
    
        private bool VerifyUserAndPwd(string user, string password)
        {
            // This is not a real authentication scheme.
            return user == password;
        }
    
        private Task<HttpResponseMessage> Unauthorized()
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(response);
            return tsc.Task;
        }
    }
    

    Uwaga

    Uwaga dotycząca zabezpieczeń: klasa AuthenticationTestHandler nie zapewnia rzeczywistego uwierzytelniania. Jest ona używana tylko do naśladowania uwierzytelniania podstawowego i nie jest bezpieczna. W swoich aplikacjach i usługach produkcyjnych musisz zaimplementować mechanizm bezpiecznego uwierzytelniania.

  5. Aby zarejestrować program obsługi komunikatów Register , dodaj następujący kod na końcu metody w pliku Program.cs :

    config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Zapisz zmiany.

Rejestrowanie na potrzeby powiadomień za pomocą zaplecza interfejsu WebAPI

W tej sekcji dodajesz nowy kontroler do zaplecza interfejsu WebAPI w celu obsługi żądań rejestracji użytkownika i urządzenia do otrzymywania powiadomień przy użyciu biblioteki klienta dla centrów powiadomień. Kontroler dodaje tag użytkownika, który został uwierzytelniony i dołączony do obiektu HttpContext przez klasę AuthenticationTestHandler. Tag ma format ciągu "username:<actual username>".

  1. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt AppBackend, a następnie wybierz polecenie Zarządzaj pakietami NuGet.

  2. W okienku po lewej stronie wybierz pozycję Online, a następnie w polu Wyszukaj wpisz ciąg Microsoft.Azure.NotificationHubs.

  3. Na liście wyników wybierz pozycję Microsoft Azure Notification Hubs, a następnie wybierz pozycję Instaluj. Zakończ instalację, a następnie zamknij okno Menedżera pakietów NuGet.

    Ta akcja spowoduje dodanie odwołania do zestawu SDK usługi Azure Notification Hubs z użyciem pakietu NuGet Microsoft.Azure.Notification Hubs.

  4. Utwórz plik nowej klasy, która reprezentuje połączenie z centrum powiadomień używane do wysyłania powiadomień. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy folder Modele, wybierz polecenie Dodaj, a następnie kliknij pozycję Klasa. Nadaj nowej klasie nazwę Notifications.cs, a następnie wybierz pozycję Dodaj, aby wygenerować klasę.

    Okno Dodawanie nowego elementu

  5. W klasie Notifications.cs dodaj następującą instrukcję using na początku pliku:

    using Microsoft.Azure.NotificationHubs;
    
  6. Zastąp definicję klasy Notifications poniższym kodem i zastąp dwa symbole zastępcze parametrami połączenia (z pełnym dostępem) dla Twojego centrum powiadomień i nazwą centrum (dostępną w witrynie Azure Portal):

    public class Notifications
    {
        public static Notifications Instance = new Notifications();
    
        public NotificationHubClient Hub { get; set; }
    
        private Notifications() {
            Hub = NotificationHubClient.CreateClientFromConnectionString("<your hub's DefaultFullSharedAccessSignature>",
                                                                            "<hub name>");
        }
    }
    

    Ważne

    Przed kontynuowaniem wprowadź nazwę i defaultFullSharedAccessSignature centrum.

  7. Następnie utwórz nowy kontroler o nazwie RegisterController. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy folder Kontrolery, wybierz polecenie Dodaj, a następnie kliknij pozycję Kontroler.

  8. Wybierz pozycję Kontroler interfejsu API — pusty, a następnie wybierz pozycję Dodaj.

  9. W polu Nazwa kontrolera wpisz ciąg RegisterController, aby nadać nazwę nowej klasie, a następnie wybierz pozycję Dodaj.

    Okno Dodawanie kontrolera.

  10. W pliku RegisterController.cs dodaj następujące instrukcje using:

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Dodaj następujący kod wewnątrz definicji klasy RegisterController. W tym kodzie dodajesz tag użytkownika, który został dołączony do obiektu HttpContext. Użytkownik został uwierzytelniony i dołączony do obiektu HttpContext przez dodany przez Ciebie filtr komunikatów, AuthenticationTestHandler. Można również dodać opcjonalne sprawdzenia w celu weryfikacji, czy użytkownik ma uprawnienia do rejestrowania żądanych tagów.

    private NotificationHubClient hub;
    
    public RegisterController()
    {
        hub = Notifications.Instance.Hub;
    }
    
    public class DeviceRegistration
    {
        public string Platform { get; set; }
        public string Handle { get; set; }
        public string[] Tags { get; set; }
    }
    
    // POST api/register
    // This creates a registration id
    public async Task<string> Post(string handle = null)
    {
        string newRegistrationId = null;
    
        // make sure there are no existing registrations for this push handle (used for iOS and Android)
        if (handle != null)
        {
            var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100);
    
            foreach (RegistrationDescription registration in registrations)
            {
                if (newRegistrationId == null)
                {
                    newRegistrationId = registration.RegistrationId;
                }
                else
                {
                    await hub.DeleteRegistrationAsync(registration);
                }
            }
        }
    
        if (newRegistrationId == null) 
            newRegistrationId = await hub.CreateRegistrationIdAsync();
    
        return newRegistrationId;
    }
    
    // PUT api/register/5
    // This creates or updates a registration (with provided channelURI) at the specified id
    public async Task<HttpResponseMessage> Put(string id, DeviceRegistration deviceUpdate)
    {
        RegistrationDescription registration = null;
        switch (deviceUpdate.Platform)
        {
            case "mpns":
                registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "wns":
                registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "apns":
                registration = new AppleRegistrationDescription(deviceUpdate.Handle);
                break;
            case "fcm":
                registration = new FcmRegistrationDescription(deviceUpdate.Handle);
                break;
            default:
                throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    
        registration.RegistrationId = id;
        var username = HttpContext.Current.User.Identity.Name;
    
        // add check if user is allowed to add these tags
        registration.Tags = new HashSet<string>(deviceUpdate.Tags);
        registration.Tags.Add("username:" + username);
    
        try
        {
            await hub.CreateOrUpdateRegistrationAsync(registration);
        }
        catch (MessagingException e)
        {
            ReturnGoneIfHubResponseIsGone(e);
        }
    
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    // DELETE api/register/5
    public async Task<HttpResponseMessage> Delete(string id)
    {
        await hub.DeleteRegistrationAsync(id);
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    private static void ReturnGoneIfHubResponseIsGone(MessagingException e)
    {
        var webex = e.InnerException as WebException;
        if (webex.Status == WebExceptionStatus.ProtocolError)
        {
            var response = (HttpWebResponse)webex.Response;
            if (response.StatusCode == HttpStatusCode.Gone)
                throw new HttpRequestException(HttpStatusCode.Gone.ToString());
        }
    }
    
  12. Zapisz zmiany.

Wysyłanie powiadomień z zaplecza interfejsu WebAPI

W tej sekcji dodasz nowego kontrolera, który opisuje sposób wysyłania powiadomień z urządzeń klienckich. Powiadomienie opiera się na tagu nazwy użytkownika, który używa biblioteki .NET usługi Azure Notification Hubs w zaplecze interfejsu WebAPI na platformie ASP.NET.

  1. Utwórz innego nowego kontrolera o nazwie NotificationsController w taki sam sposób, jak utworzono kontrolera RegisterController w poprzedniej sekcji.

  2. W pliku NotificationsController.cs dodaj następujące instrukcje using:

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. Dodaj następującą metodę do klasy NotificationsController:

    Ten kod wysyła typ powiadomienia na podstawie parametru pns usługi powiadomień platformy (PNS, Platform Notification Service). Wartość to_tag służy do ustawiania tagu username w komunikacie. Ten tag musi być zgodny z tagiem username aktywnej rejestracji centrum powiadomień. Komunikat powiadomienia jest pobierany z treści żądania POST i formatowany dla docelowej usługi PNS.

    W zależności od usługi PNS używanej do odbierania powiadomień przez obsługiwane urządzenia powiadomienia są obsługiwane przy użyciu różnych formatów. Na przykład w przypadku urządzeń z systemem Windows można użyć wyskakujących powiadomień za pomocą usługi WNS, które nie są bezpośrednio obsługiwane przez inną usługę PNS. W takim przypadku zaplecze musi sformatować powiadomienie jako obsługiwane powiadomienie w przypadku usługi PNS urządzeń, które planujesz obsługiwać. Następnie użyj odpowiedniego interfejsu API wysyłania w klasie NotificationHubClient.

    public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag)
    {
        var user = HttpContext.Current.User.Identity.Name;
        string[] userTag = new string[2];
        userTag[0] = "username:" + to_tag;
        userTag[1] = "from:" + user;
    
        Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
        HttpStatusCode ret = HttpStatusCode.InternalServerError;
    
        switch (pns.ToLower())
        {
            case "wns":
                // Windows 8.1 / Windows Phone 8.1
                var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">" + 
                            "From " + user + ": " + message + "</text></binding></visual></toast>";
                outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag);
                break;
            case "apns":
                // iOS
                var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag);
                break;
            case "fcm":
                // Android
                var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendFcmNativeNotificationAsync(notif, userTag);
                break;
        }
    
        if (outcome != null)
        {
            if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) ||
                (outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown)))
            {
                ret = HttpStatusCode.OK;
            }
        }
    
        return Request.CreateResponse(ret);
    }
    
  4. Aby uruchomić aplikację i sprawdzić dokładność pracy wykonanej do tej pory, naciśnij klawisz F5. Aplikacja otwiera przeglądarkę internetową z wyświetloną stroną główną platformy ASP.NET.

Publikowanie nowego zaplecza interfejsu WebAPI

Następnie wdrożysz tę aplikację w witrynie internetowej platformy Azure, aby udostępnić ją wszystkim urządzeniom.

  1. Kliknij prawym przyciskiem myszy projekt AppBackend, a następnie wybierz polecenie Publikuj.

  2. Wybierz pozycję Microsoft Azure App Service jako docelową lokalizację publikacji, a następnie wybierz pozycję \*\*Publikuj. Zostanie otwarte okno Tworzenie usługi App Service. W tym miejscu możesz tworzyć wszystkie niezbędne zasoby platformy Azure służące do uruchamiania aplikacji internetowej ASP.NET na platformie Azure.

    Kafelek usługi Microsoft Azure App Service

  3. W oknie Tworzenie usługi App Service wybierz swoje konto platformy Azure. Wybierz pozycję Zmień typ>aplikacji internetowej. Zachowaj wartość domyślną w polu Nazwa aplikacji internetowej i wybierz wartości w polach Subskrypcja, Grupa zasobów i Plan usługi App Service.

  4. Wybierz przycisk Utwórz.

  5. Zanotuj wartość właściwości Adres URL witryny w sekcji Podsumowanie. Ten adres URL jest Twoim punktem końcowym zaplecza w dalszej części samouczka.

  6. Kliknij pozycję Opublikuj.

Po ukończeniu pracy z kreatorem aplikacja internetowa ASP.NET zostanie opublikowana na platformie Azure, a następnie otwarta w przeglądarce domyślnej. Twoja aplikacja jest widoczna w usłudze Azure App Services.

Adres URL używa określonej wcześniej nazwy aplikacji internetowej z formatem http://< app_name.azurewebsites.net>.

Aktualizowanie kodu klienta platformy UWP

W tej sekcji aktualizujesz kod w projekcie utworzonym na potrzeby samouczka Samouczek: wysyłanie powiadomień do aplikacji platformy uniwersalnej systemu Windows przy użyciu usługi Azure Notification Hubs. Projekt powinien już być skojarzony ze Sklepem Windows. Ponadto powinien być skonfigurowany do używania centrum powiadomień. W tej sekcji dodasz kod, aby wywołać nowe zaplecze interfejsu WebAPI oraz rejestrować i wysyłać powiadomienia za jego pomocą.

  1. W programie Visual Studio otwórz rozwiązanie utworzone w ramach sekcji Samouczek: wysyłanie powiadomień do aplikacji platformy uniwersalnej systemu Windows przy użyciu usługi Azure Notification Hubs.

  2. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt platforma uniwersalna systemu Windows (UWP), a następnie kliknij polecenie Zarządzaj pakietami NuGet.

  3. Po lewej stronie wybierz pozycję Przeglądaj.

  4. W polu Wyszukaj wpisz ciąg Klient HTTP.

  5. Na liście wyników kliknij pozycję System.Net.Http, a następnie kliknij opcję Zainstaluj. Ukończ instalację.

  6. W polu Wyszukaj w menedżerze pakietów NuGet wpisz ciąg Json.net. Zainstaluj pakiet Newtonsoft.json, a następnie zamknij okno menedżera pakietów NuGet.

  7. W Eksploratorze rozwiązań kliknij projekt WindowsApp i kliknij dwukrotnie plik MainPage.xaml, aby otworzyć go w edytorze programu Visual Studio.

  8. MainPage.xaml W pliku zastąp sekcję <Grid> następującym kodem: ten kod dodaje pole tekstowe nazwy użytkownika i hasła, za pomocą którego użytkownik uwierzytelnia się. Ponadto kod dodaje pola tekstowe dla komunikatu powiadomienia oraz tagu nazwy użytkownika, który ma otrzymać powiadomienie:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    
        <TextBlock Grid.Row="0" Text="Notify Users" HorizontalAlignment="Center" FontSize="48"/>
    
        <StackPanel Grid.Row="1" VerticalAlignment="Center">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.ColumnSpan="3" Text="Username" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="UsernameTextBox" Grid.Row="1" Grid.ColumnSpan="3" Margin="20,0,20,0"/>
                <TextBlock Grid.Row="2" Grid.ColumnSpan="3" Text="Password" FontSize="24" Margin="20,0,20,0" />
                <PasswordBox Name="PasswordTextBox" Grid.Row="3" Grid.ColumnSpan="3" Margin="20,0,20,0"/>
    
                <Button Grid.Row="4" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center"
                            Content="1. Login and register" Click="LoginAndRegisterClick" Margin="0,0,0,20"/>
    
                <ToggleButton Name="toggleWNS" Grid.Row="5" Grid.Column="0" HorizontalAlignment="Right" Content="WNS" IsChecked="True" />
                <ToggleButton Name="toggleFCM" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Center" Content="FCM" />
                <ToggleButton Name="toggleAPNS" Grid.Row="5" Grid.Column="2" HorizontalAlignment="Left" Content="APNS" />
    
                <TextBlock Grid.Row="6" Grid.ColumnSpan="3" Text="Username Tag To Send To" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="ToUserTagTextBox" Grid.Row="7" Grid.ColumnSpan="3" Margin="20,0,20,0" TextWrapping="Wrap" />
                <TextBlock Grid.Row="8" Grid.ColumnSpan="3" Text="Enter Notification Message" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="NotificationMessageTextBox" Grid.Row="9" Grid.ColumnSpan="3" Margin="20,0,20,0" TextWrapping="Wrap" />
                <Button Grid.Row="10" Grid.ColumnSpan="3" HorizontalAlignment="Center" Content="2. Send push" Click="PushClick" Name="SendPushButton" />
            </Grid>
        </StackPanel>
    </Grid>
    
  9. W Eksploratorze rozwiązań otwórz plik MainPage.xaml.cs dla projektów (Windows 8.1) i (Windows Phone 8.1). Dodaj następujące instrukcje using na początku obu plików:

    using System.Net.Http;
    using Windows.Storage;
    using System.Net.Http.Headers;
    using Windows.Networking.PushNotifications;
    using Windows.UI.Popups;
    using System.Threading.Tasks;
    
  10. W pliku MainPage.xaml.cs dla projektu WindowsApp dodaj następujący element członkowski do klasy MainPage. Pamiętaj, aby zastąpić ciąg <Enter Your Backend Endpoint> wcześniej pozyskanym, faktycznym punktem końcowym zaplecza. Na przykład http://mybackend.azurewebsites.net.

    private static string BACKEND_ENDPOINT = "<Enter Your Backend Endpoint>";
    
  11. Dodaj poniższy kod do klasy MainPage w pliku MainPage.xaml.cs dla projektów (Windows 8.1) i (Windows Phone 8.1).

    Metoda PushClick to procedura obsługi kliknięcia dla przycisku Send Push (Wyślij powiadomienie push). Metoda wywołuje zaplecze, aby wyzwolić powiadomienie do wszystkich urządzeń z tagiem nazwy użytkownika, który pasuje do parametru to_tag. Komunikat powiadomienia jest wysyłany jako zawartość JSON w treści żądania.

    Metoda LoginAndRegisterClick to procedura obsługi kliknięcia dla przycisku Login and register (Zaloguj i zarejestruj się). Zapisuje ona podstawowy token uwierzytelniania (reprezentuje dowolny token używany w danym schemacie uwierzytelniania) w magazynie lokalnym, a następnie używa metody RegisterClient, aby dokonać rejestracji na potrzeby powiadomień przy użyciu zaplecza.

    private async void PushClick(object sender, RoutedEventArgs e)
    {
        if (toggleWNS.IsChecked.Value)
        {
            await sendPush("wns", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
        }
        if (toggleFCM.IsChecked.Value)
        {
            await sendPush("fcm", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
        }
        if (toggleAPNS.IsChecked.Value)
        {
            await sendPush("apns", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
    
        }
    }
    
    private async Task sendPush(string pns, string userTag, string message)
    {
        var POST_URL = BACKEND_ENDPOINT + "/api/notifications?pns=" +
            pns + "&to_tag=" + userTag;
    
        using (var httpClient = new HttpClient())
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]);
    
            try
            {
                await httpClient.PostAsync(POST_URL, new StringContent("\"" + message + "\"",
                    System.Text.Encoding.UTF8, "application/json"));
            }
            catch (Exception ex)
            {
                MessageDialog alert = new MessageDialog(ex.Message, "Failed to send " + pns + " message");
                alert.ShowAsync();
            }
        }
    }
    
    private async void LoginAndRegisterClick(object sender, RoutedEventArgs e)
    {
        SetAuthenticationTokenInLocalStorage();
    
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
        // The "username:<user name>" tag gets automatically added by the message handler in the backend.
        // The tag passed here can be whatever other tags you may want to use.
        try
        {
            // The device handle used is different depending on the device and PNS.
            // Windows devices use the channel uri as the PNS handle.
            await new RegisterClient(BACKEND_ENDPOINT).RegisterAsync(channel.Uri, new string[] { "myTag" });
    
            var dialog = new MessageDialog("Registered as: " + UsernameTextBox.Text);
            dialog.Commands.Add(new UICommand("OK"));
            await dialog.ShowAsync();
            SendPushButton.IsEnabled = true;
        }
        catch (Exception ex)
        {
            MessageDialog alert = new MessageDialog(ex.Message, "Failed to register with RegisterClient");
            alert.ShowAsync();
        }
    }
    
    private void SetAuthenticationTokenInLocalStorage()
    {
        string username = UsernameTextBox.Text;
        string password = PasswordTextBox.Password;
    
        var token = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
        ApplicationData.Current.LocalSettings.Values["AuthenticationToken"] = token;
    }
    
  12. Otwórz plik App.xaml.cs i znajdź wywołanie metody InitNotificationsAsync() w programie obsługi zdarzeń OnLaunched(). Oznacz wywołanie metody InitNotificationsAsync() jako komentarz lub usuń je. Procedura obsługi przycisków inicjuje rejestracje powiadomień:

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        //InitNotificationsAsync();
    
  13. Kliknij prawym przyciskiem myszy projekt WindowsApp, kliknij polecenie Dodaj, a następnie kliknij polecenie Klasa. Nadaj klasie nazwę RegisterClient.cs, a następnie kliknij przycisk OK, aby wygenerować klasę.

    Ta klasa opakowuje wywołania REST wymagane do kontaktowania się z zapleczem aplikacji, aby przeprowadzać rejestrację na potrzeby powiadomień push. Ponadto zapisuje lokalnie identyfikatory registrationId utworzone przez centrum powiadomień zgodnie z opisem w sekcji Rejestrowanie z poziomu zaplecza aplikacji. Klasa używa tokenu autoryzacji przechowywanego w magazynie lokalnym po kliknięciu przycisku Login and register (Zaloguj i zarejestruj się).

  14. Dodaj następujące instrukcje using na początku pliku RegisterClient.cs:

    using Windows.Storage;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using Newtonsoft.Json;
    using System.Threading.Tasks;
    using System.Linq;
    
  15. Dodaj następujący kod wewnątrz RegisterClient definicji klasy:

    private string POST_URL;
    
    private class DeviceRegistration
    {
        public string Platform { get; set; }
        public string Handle { get; set; }
        public string[] Tags { get; set; }
    }
    
    public RegisterClient(string backendEndpoint)
    {
        POST_URL = backendEndpoint + "/api/register";
    }
    
    public async Task RegisterAsync(string handle, IEnumerable<string> tags)
    {
        var regId = await RetrieveRegistrationIdOrRequestNewOneAsync();
    
        var deviceRegistration = new DeviceRegistration
        {
            Platform = "wns",
            Handle = handle,
            Tags = tags.ToArray<string>()
        };
    
        var statusCode = await UpdateRegistrationAsync(regId, deviceRegistration);
    
        if (statusCode == HttpStatusCode.Gone)
        {
            // regId is expired, deleting from local storage & recreating
            var settings = ApplicationData.Current.LocalSettings.Values;
            settings.Remove("__NHRegistrationId");
            regId = await RetrieveRegistrationIdOrRequestNewOneAsync();
            statusCode = await UpdateRegistrationAsync(regId, deviceRegistration);
        }
    
        if (statusCode != HttpStatusCode.Accepted && statusCode != HttpStatusCode.OK)
        {
            // log or throw
            throw new System.Net.WebException(statusCode.ToString());
        }
    }
    
    private async Task<HttpStatusCode> UpdateRegistrationAsync(string regId, DeviceRegistration deviceRegistration)
    {
        using (var httpClient = new HttpClient())
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string) settings["AuthenticationToken"]);
    
            var putUri = POST_URL + "/" + regId;
    
            string json = JsonConvert.SerializeObject(deviceRegistration);
                            var response = await httpClient.PutAsync(putUri, new StringContent(json, Encoding.UTF8, "application/json"));
            return response.StatusCode;
        }
    }
    
    private async Task<string> RetrieveRegistrationIdOrRequestNewOneAsync()
    {
        var settings = ApplicationData.Current.LocalSettings.Values;
        if (!settings.ContainsKey("__NHRegistrationId"))
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]);
    
                var response = await httpClient.PostAsync(POST_URL, new StringContent(""));
                if (response.IsSuccessStatusCode)
                {
                    string regId = await response.Content.ReadAsStringAsync();
                    regId = regId.Substring(1, regId.Length - 2);
                    settings.Add("__NHRegistrationId", regId);
                }
                else
                {
                    throw new System.Net.WebException(response.StatusCode.ToString());
                }
            }
        }
        return (string)settings["__NHRegistrationId"];
    
    }
    
  16. Zapisz wszystkie zmiany.

Testowanie aplikacji

  1. Uruchom aplikację w obu systemach Windows.

  2. Wprowadź nazwę użytkownika i hasło, jak pokazano na poniższym zrzucie ekranu. Powinny różnić się od nazwy użytkownika i hasła, które zostały wprowadzone w systemie Windows Phone.

  3. Kliknij przycisk Log in and register (Zaloguj i zarejestruj się) i upewnij się, że okno dialogowe wyświetla potwierdzenie zalogowania. Ponadto ten kod włącza przycisk Send Push (Wyślij powiadomienie push).

    Zrzut ekranu przedstawiający aplikację usługi Notification Hubs z wypełnioną nazwą użytkownika i hasłem.

  4. Następnie w polu Recipient Username Tag (Tag nazwy użytkownika odbiorcy) wprowadź zarejestrowaną nazwę użytkownika. Wprowadź komunikat powiadomienia i kliknij opcję Send Push (Wyślij powiadomienie push).

  5. Komunikat powiadomienia otrzymają tylko te urządzenia, które zarejestrowały się przy użyciu pasującego tagu nazwy użytkownika.

    Zrzut ekranu przedstawiający aplikację usługi Notification Hubs z komunikatem wypchniętym.

Następne kroki

W tym samouczku przedstawiono sposób wysyłania powiadomień push do konkretnych użytkowników, którzy mają tagi skojarzone ze swoimi rejestracjami. Aby dowiedzieć się, jak wypychać powiadomienia oparte na lokalizacji, przejdź do następującego samouczka: