Tutorial: enviar notificações para utilizadores específicos com Hubs de Notificação do Azure

Descrição Geral

Este tutorial descreve como utilizar os Hubs de Notificação do Azure para enviar notificações push a um utilizador de aplicações específico num dispositivo específico. Um back-end de ASP.NET WebAPI é utilizado para autenticar clientes. Quando o back-end autentica um utilizador de aplicação de cliente, adiciona automaticamente uma etiqueta ao registo de notificação. O back-end utiliza esta etiqueta para enviar notificações para o utilizador específico.

Nota

O código concluído para este tutorial pode ser encontrado no GitHub.

Neste tutorial, siga os seguintes passos:

  • Criar o Projeto WebAPI
  • Autenticar clientes no back-end de WebAPI
  • Utilizar o back-end de WebAPI para registar notificações
  • Enviar notificações a partir do back-end de WebAPI
  • Publicar o back-end de WebAPI novo
  • Atualizar o código do projeto de cliente
  • Testar a aplicação

Pré-requisitos

Este tutorial baseia-se no projeto do Visual Studio e no Hub de Notificação que criou no Tutorial: enviar notificações para aplicações de Plataforma Universal do Windows com Hubs de Notificação do Azure. Por isso, conclua-o antes de iniciar este tutorial.

Nota

Se estiver a utilizar Aplicações Móveis no Serviço de Aplicações do Azure como o seu serviço de back-end, veja a secção Versão para Aplicações Móveis deste tutorial.

Criar o Projeto WebAPI

As secções seguintes abordam a criação de um novo back-end de ASP.NET WebAPI. Este processo tem três objetivos principais:

  • Autenticar os clientes: é adicionado um processador de mensagens para autenticar os pedidos dos clientes e associar os utilizadores aos pedidos.
  • Registar-se para receber notificações ao utilizar o back-end de WebAPI: é adicionado um controlador para processar registos novos, para que um dispositivo de cliente receba notificações. O nome de utilizador autenticado é adicionado automaticamente ao registo como uma etiqueta.
  • Enviar notificações para os clientes: é adicionado um controlador para permitir que os utilizadores acionem um envio seguro para dispositivos e clientes associados à etiqueta.

Crie o novo back-end da API Web ASP.NET Core 6.0 efetuando as seguintes ações:

Para confirmar, inicie o Visual Studio. No menu Ferramentas, selecione Extensões e Atualizações. Procure o Gestor de Pacotes de NuGet na sua versão do Visual Studio e verifique se tem a versão mais recente. Se a sua versão não for a versão mais recente, desinstale-a e, em seguida, reinstale o Gestor de Pacotes de NuGet.

Captura de ecrã da caixa de diálogo Extensões e Atualizações com o pacote NuGet Manage for Visual Studios realçado.

Nota

Certifique-se de que instalou o SDK do Azure do Visual Studio para implementação de sites.

  1. Inicie o Visual Studio ou o Visual Studio Express.

  2. Selecione Explorador de Servidores e inicie sessão na sua conta do Azure. Para criar os recursos do site na sua conta, tem de ter sessão iniciada.

  3. No menu Ficheiro do Visual Studio, selecione Novo>Projeto.

  4. Introduza API Web na caixa de pesquisa.

  5. Selecione o modelo de projeto da API Web ASP.NET Core e selecione Seguinte.

  6. Na caixa de diálogo Configurar o novo projeto , atribua o nome AppBackend ao projeto e selecione Seguinte.

  7. Na caixa de diálogo Informações adicionais :

    • Confirme que o Framework é .NET 6.0 (suporte a longo prazo).
    • Confirme se a caixa de verificação Utilizar controladores (desmarcar para utilizar APIs mínimas) está selecionada.
    • Desmarque Ativar suporte openAPI.
    • Selecione Criar.

Remover os ficheiros de modelo WeatherForecast

  1. Remova os ficheiros de exemplo WeatherForecast.cs e Controllers/WeatherForecastController.cs do novo projeto AppBackend .
  2. Abra Properties\launchSettings.json.
  3. Altere as propriedades launchUrl de weatherforcast para appbackend.

Na janela Configurar Aplicação Web do Microsoft Azure, selecione uma subscrição e, em seguida, na lista Plano do Serviço de Aplicações, efetue uma das seguintes ações:

  • Selecione um Serviço de Aplicações do Azure plano que já criou.
  • Selecione Criar um novo plano do serviço de aplicações e, em seguida, crie um.

Não precisa de uma base de dados para este tutorial. Depois de selecionar o seu plano do serviço de aplicações, selecione OK para criar o projeto.

A janela Configurar Aplicação Web do Microsoft Azure

Se não vir esta página para configurar o plano do serviço de aplicações, continue com o tutorial. Pode configurá-la enquanto publica a aplicação mais tarde.

Autenticar clientes no back-end de WebAPI

Nesta secção, crie uma nova classe de processadores de mensagens com o nome AuthenticationTestHandler para o back-end novo. Esta classe é derivada de DelegatingHandler e adicionada como um processador de mensagens, para processar todos os pedidos enviados para o back-end.

  1. No Explorador de Soluções, clique com o botão direito do rato no projeto AppBackend, selecione Adicionar e, em seguida, selecione Classe.

  2. Dê o nome AuthenticationTestHandler.cs à classe e selecione Adicionar para gerar a classe. Esta classe autentica utilizadores com a Autenticação Básica, para simplicidade. A sua aplicação pode utilizar qualquer esquema de autenticação.

  3. No AuthenticationTestHandler.cs, adicione as instruções using seguintes:

    using System.Net.Http;
    using System.Threading;
    using System.Security.Principal;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
  4. No AuthenticationTestHandler.cs, substitua a definição de classe AuthenticationTestHandler pelo seguinte código:

    O processador autoriza o pedido quando se verificarem as três condições seguintes:

    • O pedido inclui o cabeçalho Autorização.
    • O pedido utiliza a autenticação básica.
    • A cadeia de nome de utilizador e a cadeia de palavra-passe são a mesma cadeia.

    Caso contrário, o pedido é rejeitado. Esta autenticação não é uma verdadeira abordagem de autenticação e autorização. É apenas um exemplo simples para este tutorial.

    Se AuthenticationTestHandler autenticar e autorizar a mensagem do pedido, o utilizador de autenticação básica é anexado ao pedido atual em HttpContext. As informações do utilizador em HttpContext serão utilizadas por outro controlador (RegisterController) mais tarde, para adicionar uma etiqueta ao pedido de registo de notificação.

    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;
        }
    }
    

    Nota

    Nota de segurança: a classe AuthenticationTestHandler não fornece uma autenticação verdadeira. É utilizada apenas para imitar a autenticação básica e não é segura. Tem de implementar um mecanismo de autenticação segura nos seus serviços e aplicações de produção.

  5. Para registar o processador de mensagens, adicione o seguinte código no final do Register método no ficheiro Program.cs :

    config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Guarde as alterações.

Utilizar o back-end de WebAPI para registar notificações

Nesta secção, adicione um controlador novo ao back-end de WebAPI para processar pedidos de registo de um utilizador e de um dispositivo para as notificações, através da biblioteca de cliente dos hubs de notificação. O controlador adiciona uma etiqueta de utilizador para o utilizador que AuthenticationTestHandler autenticou e anexou a HttpContext. A etiqueta tem o formato de cadeia "username:<actual username>".

  1. No Explorador de Soluções, clique com o botão direito no projeto AppBackend e, em seguida, selecione Gerir Pacotes de NuGet.

  2. No painel esquerdo, selecione Online e, na caixa Procurar, escreva Microsoft.Azure.NotificationHubs.

  3. Na lista de resultados, selecione Hubs de Notificação do Microsoft Azure e, em seguida, selecione Instalar. Conclua a instalação e feche a janela Gestor de Pacotes de NuGet.

    Esta ação adiciona uma referência ao SDK dos Hubs de Notificação do Azure mediante a utilização do Pacote NuGet Microsoft.Azure.Notification Hubs.

  4. Crie um ficheiro de classe novo que represente a ligação ao hub de notificação utilizado para enviar notificações. No Explorador de Soluções, clique com o botão direito do rato na pasta Modelos, selecione Adicionar e, em seguida, selecione Classe. Dê o nome Notifications.cs à classe nova e selecione Adicionar para gerá-la.

    A janela Adicionar Novo Item

  5. Em Notifications.cs, adicione a instrução using à parte superior do ficheiro:

    using Microsoft.Azure.NotificationHubs;
    
  6. Substitua a definição de classe Notifications pelo código seguinte e substitua os dois marcadores de posição pela cadeia de ligação (com acesso total) do seu hub de notificação e o nome do hub (disponível no portal do Azure):

    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>");
        }
    }
    

    Importante

    Introduza o nome e a DefaultFullSharedAccessSignature do seu hub antes de continuar.

  7. Em seguida, crie um controlador novo com o nome RegisterController. No Explorador de Soluções, clique com o botão direito do rato na pasta Controladores, selecione Adicionar e, em seguida, selecione Controlador.

  8. Selecione Controlador de API – Vazio e, em seguida, selecione Adicionar.

  9. Na caixa Nome do controlador, escreva RegisterController para designar a classe nova e selecione Adicionar.

    A janela Adicionar Controlador.

  10. No RegisterController.cs, adicione as instruções using seguintes:

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Adicione o código seguinte dentro da definição de classe RegisterController. Neste código, adicione uma etiqueta de utilizador para o utilizador que está anexado a HttpContext. O utilizador foi autenticado e anexado a HttpContext através do filtro de mensagem que adicionou, AuthenticationTestHandler. Também pode adicionar verificações opcionais para confirmar que o utilizador tem direitos para se registar nas etiquetas pedidas.

    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. Guarde as alterações.

Enviar notificações a partir do back-end de WebAPI

Nesta secção, irá adicionar um novo controlador que indica uma forma de os dispositivos de cliente enviarem uma notificação. A notificação baseia-se na etiqueta de nome de utilizador que utiliza a Biblioteca .NET dos Hubs de Notificação do Azure no back-end de ASP.NET WebAPI.

  1. Crie outro controlador novo com o nome NotificationsController da mesma forma que criou o RegisterController na secção anterior.

  2. No NotificationsController.cs, adicione as instruções using seguintes:

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. Adicione o método seguinte à classe NotificationsController:

    Este código envia um tipo de notificação com base no parâmetro pns do Serviço de Notificação de Plataforma (PNS). O valor de to_tag é utilizado para definir a etiqueta nome de utilizador na mensagem. Esta etiqueta tem de corresponder a uma etiqueta de nome de utilizador de um registo de hub de notificação ativo. A mensagem da notificação é retirada do corpo do pedido POST e formatada para o PNS de destino.

    Consoante o PNS que os seus dispositivos suportados utilizam para receber notificações, estas são suportadas com vários formatos. Por exemplo, em dispositivos Windows, poderá utilizar uma notificação de alerta com WNS que não seja diretamente suportada por outro PNS. Nesse caso, o seu back-end tem de formatar a notificação de modo a que seja suportada pelo PNS dos dispositivos que pretende incluir. Em seguida, utilize a API de envio adequada na classe 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. Para executar a aplicação e garantir a precisão do seu trabalho até ao momento, prima a tecla F5. A aplicação abre um browser e é apresentada na home page do ASP.NET.

Publicar o back-end de WebAPI novo

Em seguida, implemente a aplicação num site do Azure para que seja acessível a partir de todos os dispositivos.

  1. Clique com o botão direito do rato no projeto AppBackend e selecione Publicar.

  2. Selecione Serviço de Aplicações do Microsoft Azure como o destino da publicação e selecione \*\*Publicar. A janela Criar Serviço de Aplicações é aberta. Aí, pode criar todos os recursos do Azure necessários para executar a aplicação Web ASP.NET no Azure.

    O mosaico do Serviço de Aplicações do Microsoft Azure

  3. Na janela Criar Serviço de Aplicações, selecione a sua conta do Azure. Selecione Alterar Tipo de>Aplicação Web. Mantenha o Nome da Aplicação Web predefinido e, em seguida, selecione a Subscrição, o Grupo de Recursos e o Plano do Serviço de Aplicações.

  4. Selecione Criar.

  5. Anote a propriedade URL do Site, na secção Resumo. Este URL será o seu ponto final de back-end mais adiante no tutorial.

  6. Selecione Publicar.

Depois de concluir o assistente, este publica a aplicação Web ASP.NET no Azure e, em seguida, abre a aplicação no browser predefinido. A aplicação é visualizável nos Serviços Aplicacionais do Azure.

O URL utiliza o nome da aplicação Web que especificou anteriormente, com o formato http://< app_name.azurewebsites.net>.

Atualizar o código do cliente UWP

Nesta secção, atualize o código no projeto que concluiu no Tutorial: enviar notificações para aplicações de Plataforma Universal do Windows com Hubs de Notificação do Azure. O projeto já deve estar associado à Microsoft Store. Também deve estar configurado para utilizar o seu Hub de Notificação. Nesta secção, adicione o código para chamar o novo back-end de WebAPI e utilize-o para registar e enviar notificações.

  1. No Visual Studio, abra a solução que criou para o Tutorial: enviar notificações para aplicações de Plataforma Universal do Windows com Hubs de Notificação do Azure.

  2. No Explorador de Soluções, clique com o botão direito do rato no projeto Plataforma Universal do Windows (UWP) e, em seguida, clique em Gerir Pacotes NuGet.

  3. No lado esquerdo, selecione Procurar.

  4. Na caixa Procurar, escreva Cliente HTTP.

  5. Na lista de resultados, clique em System.Net.Http e clique em Instalar. Conclua a instalação.

  6. Na caixa Procurar no NuGet, escreva Json.net. Instale o pacote Newtonsoft.json e, em seguida, feche a janela Gestor de Pacote NuGet.

  7. No Explorador de Soluções, no projeto WindowsApp, faça duplo clique em MainPage.xaml para o abrir no editor do Visual Studio.

  8. MainPage.xaml No ficheiro, substitua a <Grid> secção pelo seguinte código: este código adiciona uma caixa de texto de nome de utilizador e palavra-passe que o utilizador autentica. Também adiciona caixas de texto para a mensagem de notificação e a etiqueta de nome de utilizador que deve receber a notificação:

    <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. No Explorador de Soluções, abra o MainPage.xaml.cs ficheiro para os projetos (Windows 8.1) e (Windows Phone 8.1). Adicione as seguintes declarações using na parte superior dos ficheiros:

    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. No MainPage.xaml.cs para o projeto WindowsApp , adicione o seguinte membro à MainPage classe . Certifique-se de que substitui o <Enter Your Backend Endpoint> pelo ponto final de back-end real obtido anteriormente. Por exemplo, http://mybackend.azurewebsites.net.

    private static string BACKEND_ENDPOINT = "<Enter Your Backend Endpoint>";
    
  11. Adicione o código abaixo à classe MainPage em MainPage.xaml.cs para os projetos (Windows 8.1) e (Windows Phone 8.1).

    O método PushClick é o processador de cliques do botão Enviar Notificação Push. Chama o back-end para acionar uma notificação para todos os dispositivos com uma etiqueta de nome de utilizador que corresponde ao parâmetro to_tag. A mensagem de notificação é enviada como conteúdo JSON no corpo do pedido.

    O método LoginAndRegisterClick é o processador de cliques do botão Iniciar sessão e registar. Armazena o token de autenticação básico (representa qualquer token que o seu esquema de autenticação utilize) no armazenamento local e, em seguida, utiliza o RegisterClient para se registar para receber notificações com o back-end.

    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. Abra App.xaml.cs e localize a chamada para InitNotificationsAsync() no OnLaunched() processador de eventos. Comente ou elimine a chamada para InitNotificationsAsync(). O processador de botões inicializa os registos de notificação:

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        //InitNotificationsAsync();
    
  13. Clique com o botão direito do rato no projeto WindowsApp, clique em Adicionar e em Classe. Atribua um nome à classe RegisterClient.cse, em seguida, clique em OK para gerar a classe .

    Esta classe encapsula as chamadas REST necessárias para contactar o back-end da aplicação, para se registar para receber notificações push. Também armazena localmente os registrationIds criados pelo Hub de Notificação conforme detalhado em Registar-se a partir do back-end da aplicação. Utiliza um token de autorização guardado no armazenamento local quando clica no botão Iniciar sessão e registar.

  14. Adicione as seguintes declarações using na parte superior do ficheiro 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. Adicione o seguinte código dentro da definição de RegisterClient classe:

    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. Guarde todas as alterações.

Testar a Aplicação

  1. Inicie a aplicação em ambos os Windows.

  2. Introduza um Nome de Utilizador e Palavra-passe conforme apresentado no ecrã abaixo. Devem diferir do nome de utilizador e da palavra-passe que introduziu no Windows Phone.

  3. Clique em Iniciar sessão e registar e verifique se uma caixa de diálogo mostra que iniciou sessão. Este código também ativa o botão Enviar Notificação Push.

    Captura de ecrã da aplicação Notification Hubs a mostrar o nome de utilizador e a palavra-passe preenchidos.

  4. Em seguida, no campo Etiqueta de Nome de Utilizador de Destinatário, introduza o nome de utilizador registado. Introduza a mensagem de notificação e clique em Enviar Notificação Push.

  5. Apenas os dispositivos registados com a etiqueta de nome de utilizador correspondente recebem a mensagem de notificação.

    Captura de ecrã da aplicação Notification Hubs a mostrar a mensagem que foi enviada.

Passos seguintes

Neste tutorial, aprendeu a enviar notificações push para utilizadores específicos que têm etiquetas associadas aos respetivos registos. Para saber como enviar notificações push com base na localização, avance para o seguinte tutorial: