Compartir vía


Tutorial: Envío de notificaciones a usuarios concretos mediante Azure Notification Hubs

Información general

Este tutorial describe cómo utilizar los Centros de notificaciones de Azure para enviar notificaciones push a un usuario de aplicaciones determinado en un dispositivo concreto. Se usa un back-end de WebAPI de ASP.NET para autenticar a los clientes. Cuando el back-end autentica un usuario de la aplicación cliente, agrega automáticamente una etiqueta al registro de notificaciones. El back-end utiliza dicha etiqueta para enviar notificaciones al usuario concreto.

Nota

El código completo de este tutorial se puede encontrar en GitHub.

En este tutorial, realizará los siguientes pasos:

  • Creación del proyecto de API web
  • Autenticar clientes en el back-end de WebAPI
  • Registrar notificaciones mediante el back-end de WebAPI
  • Enviar notificaciones desde el back-end de WebAPI
  • Publicación del nuevo back-end de WebAPI
  • Actualización del código para el proyecto de cliente
  • Prueba de la aplicación

Requisitos previos

Este tutorial se basa en el centro de notificaciones y el proyecto de Visual Studio que creó en el Tutorial: Envío de notificaciones a aplicaciones de Plataforma universal de Windows mediante Azure Notification Hubs. Por consiguiente, complételo antes de iniciar este.

Nota

Si usa Mobile Apps como su servicio back-end en Azure App Service, consulte la versión de Mobile Apps de este tutorial.

Creación del proyecto de API web

En las secciones siguientes se describe la creación de un nuevo back-end de ASP.NET WebAPI. Este proceso tiene tres objetivos principales:

  • Autenticación de clientes: se agrega un controlador de mensajes para autenticar las solicitudes de cliente y asociar el usuario a la solicitud.
  • Registro para recibir notificaciones mediante el back-end de WebAPI: se agrega un controlador para administrar los registros nuevos de un dispositivo cliente para que reciba notificaciones. El nombre de usuario autenticado se agrega automáticamente al registro como etiqueta.
  • Envío de notificaciones a los clientes: se agrega un controlador para que los usuarios puedan desencadenar una inserción segura en los dispositivos y clientes asociados con la etiqueta.

Realice las siguientes acciones para crear el nuevo back-end de API web de ASP.NET Core 6.0:

Para comprobarlo, inicie Visual Studio. En el menú Herramientas, seleccione Extensiones y actualizaciones. Busque el Administrador de paquetes NuGet correspondiente a su versión de Visual Studio y asegúrese de que tiene la versión más reciente. Si no es la más reciente, se debe desinstalar y volver a instalar el Administrador de paquetes NuGet.

Captura de pantalla del cuadro de diálogo Extensiones y actualizaciones con el paquete NuGet de administración para Visual Studio resaltado.

Nota

Asegúrese de que ha instalado el SDK de Azure para Visual Studio para la implementación de sitios web.

  1. Inicie Visual Studio o Visual Studio Express.

  2. Seleccione el Explorador de servidores e inicie sesión en su cuenta de Azure. Para crear los recursos del sitio web en su cuenta, tiene que iniciar sesión.

  3. En el menú Archivo de Visual Studio, seleccione Nuevo>Proyecto.

  4. Escriba API web en el cuadro de búsqueda.

  5. Seleccione la plantilla de proyecto ASP.NET Core Web API y, a continuación, Siguiente.

  6. En el cuadro de diálogo Configurar el nuevo proyecto, asigne al proyecto el nombre AppBackend y seleccione Siguiente.

  7. En el cuadro de diálogo Información adicional:

    • Confirme que el Marco es .NET 6.0 (Compatibilidad a largo plazo).
    • Confirme que la casilla Use controllers(uncheck to use minimal APIs) [Usar controladores (desactivar para usar API mínimas)] está activada.
    • Desactive Habilitar compatibilidad con OpenAPI.
    • Seleccione Crear.

Eliminación de los archivos de plantilla WeatherForecast

  1. Quite los archivos de ejemplo WeatherForecast.cs y Controllers/WeatherForecastController.cs del nuevo proyecto AppBackend.
  2. Abra Properties\launchSettings.json.
  3. Cambie las propiedades launchUrl de weatherforcast a appbackend.

En la ventana Configurar aplicación web de Microsoft Azure, seleccione una suscripción y, en la listaPlan de App Service, realice una de las siguientes acciones:

  • Seleccione un plan de Azure App Service que ya haya creado.
  • Seleccione Crear un nuevo plan de App Service para crear uno.

No es necesario una base de datos para este tutorial. Una vez seleccionado el plan de App Service, seleccione Aceptar para crear el proyecto.

Ventana Configurar aplicación web de Microsoft Azure

Si no ve esta página para configurar el plan de App Service, continúe con el tutorial. Se puede configurar al publicar la aplicación más adelante.

Autenticar clientes en el back-end de WebAPI

En esta sección se crea una clase de controlador de mensajes llamada AuthenticationTestHandler para el nuevo back-end. Esta clase deriva de DelegatingHandler y se agrega como controlador de mensajes para que procese todas las solicitudes que lleguen al back-end.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto AppBackend, y seleccione Agregar y Clase.

  2. Asigne a la nueva clase el nombre AuthenticationTestHandler.cs y seleccione Agregar para generar la clase. Para simplificar, esta clase autentica a los usuarios con Autenticación básica. La aplicación puede utilizar cualquier esquema de autenticación.

  3. En AuthenticationTestHandler.cs, agregue las siguientes instrucciones using :

    using System.Net.Http;
    using System.Threading;
    using System.Security.Principal;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
  4. En AuthenticationTestHandler.cs, reemplace la definición de clase AuthenticationTestHandler con el código siguiente:

    Este controlador autoriza la solicitud cuando se cumplen las tres condiciones siguientes:

    • La solicitud incluya un encabezado Autorización.
    • La solicitud utiliza la autenticación básica .
    • La cadena de nombre de usuario y la cadena de contraseña son la misma cadena.

    En caso contrario, la solicitud se rechaza. Esta autenticación no es un enfoque de autorización y autenticación real. Es solo un ejemplo sencillo para este tutorial.

    Si AuthenticationTestHandler autentica y autoriza el mensaje de solicitud, el usuario de autenticación básica se adjuntará a la solicitud actual en HttpContext. Otro controlador (RegisterController) usará después la información de usuario de HttpContext para agregar una etiqueta a la solicitud de registro de notificación.

    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 seguridad: la clase AuthenticationTestHandler no proporciona una autenticación verdadera. Se utiliza únicamente para simular una autenticación básica y no es segura. Debe implementar un mecanismo de autenticación seguro en las aplicaciones y servicios de producción.

  5. Para registrar el controlador de mensajes, agregue el siguiente código al final del método Register en el archivo Program.cs:

    config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Guarde los cambios.

Registrar notificaciones mediante el back-end de WebAPI

En esta sección, agregaremos un nuevo controlador al back-end de WebAPI para administrar las solicitudes de registro de un usuario y un dispositivo para que reciban notificaciones mediante la biblioteca cliente de los centros de notificaciones. El controlador agrega una etiqueta de usuario al usuario que el AuthenticationTestHandlerautenticó y adjuntó a HttpContext. La etiqueta tiene el formato de cadena, "username:<actual username>".

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto AppBackend y seleccione Administrar paquetes NuGet.

  2. En el panel izquierdo, seleccione En línea y en el cuadro Buscar, escriba Microsoft.Azure.NotificationHubs.

  3. En la lista de resultados, seleccione Microsoft Azure Notification Hubs e Instalar. Complete la instalación y cierre la ventana del Administrador de paquetes NuGet.

    Esta acción agrega una referencia al SDK de Azure Notification Hubs mediante el paquete NuGet Microsoft.Azure.NotificationHubs.

  4. Cree un archivo de clase que represente la conexión con el centro de notificaciones de envío. En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Modelos, seleccione Agregar y Clase. Asigne el nombre a la nueva clase Notifications.cs y seleccione Agregar para generar la clase.

    Ventana Agregar nuevo elemento

  5. En Notifications.cs, agregue la siguiente instrucción using en la parte superior del archivo:

    using Microsoft.Azure.NotificationHubs;
    
  6. Reemplace la definición de clase Notifications con el código siguiente y los dos marcadores de posición con la cadena de conexión (de acceso total) del centro de notificaciones y el nombre del centro (disponible en el Portal de 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

    Escriba el nombre y elemento DefaultFullSharedAccessSignature del centro antes de continuar.

  7. A continuación, cree un controlador denominado RegisterController. En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Controladores, y seleccione Agregar y Controlador.

  8. Seleccione Controlador de API: en blanco y Agregar.

  9. En el cuadro Nombre del controlador, escriba RegisterController para denominar la nueva clase y seleccione Agregar.

    Ventana Agregar controlador.

  10. En RegisterController.cs, agregue las siguientes instrucciones using :

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Agregue el siguiente código a la definición de clase RegisterController . En este código, agregamos una etiqueta de usuario para el usuario asociado a HttpContext. El usuario se autenticó y se asoció a HttpContext mediante un filtro de mensaje que agregó, AuthenticationTestHandler. También puede realizar comprobaciones opcionales para comprobar que el usuario puede registrarse para las etiquetas solicitadas.

    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 los cambios.

Enviar notificaciones desde el back-end de WebAPI

En esta sección se agrega un nuevo controlador que expone una manera de enviar notificaciones para los dispositivos cliente. La notificación se basa en la etiqueta de nombre de usuario que usa la biblioteca .NET de Microsoft Azure Notification Hubs en el back-end de ASP.NET WebAPI.

  1. Cree otro controlador denominado NotificationsController del mismo modo que creó RegisterController en la sección anterior.

  2. En NotificationsController.cs, agregue las siguientes instrucciones using :

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. Agregue el método siguiente a la clase NotificationsController:

    Este código envía un tipo de notificación basado en el parámetro pns del servicio Sistema de notificación de plataforma (PNS). El valor de to_tag se usa para definir la etiqueta username en el mensaje. Esta etiqueta debe coincidir con una etiqueta de nombre de usuario de un registro de un centro de notificaciones activo. El mensaje de notificación se extrae del cuerpo de la solicitud POST y se formatea para el PNS de destino.

    Dependiendo del PNS que usen los dispositivos compatibles para recibir notificaciones, se admiten distintos formatos. Por ejemplo, en dispositivos Windows, puede usar una notificación del sistema con WNS que no sea compatible directamente con otro PNS. En este caso, el back-end debe dar un formato a la notificación que sea compatible con el PNS de los dispositivos que prevea admitir. Posteriormente, use la API de envío adecuada en la clase 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 ejecutar la aplicación y garantizar que hasta ahora todo es correcto, seleccione la tecla F5. La aplicación abre un explorador web y se muestra en la página de inicio de ASP.NET.

Publicación del nuevo back-end de WebAPI

A continuación implementaremos la aplicación en un sitio web de Azure para que todos los dispositivos puedan acceder a ella.

  1. Haga clic con el botón derecho en el proyecto AppBackend y seleccione Publicar.

  2. Seleccione Microsoft Azure App Service como destino de publicación y, luego, \*\*Publicar. La ventana Crear servicio de aplicaciones se abre. Aquí puede crear todos los recursos de Azure necesarios para ejecutar la aplicación web ASP.NET en Azure.

    Icono de Microsoft Azure App Service

  3. En la ventana Crear servicio de aplicaciones, seleccione la cuenta de Azure. Seleccione Cambiar tipo>Aplicación web. Mantenga el Nombre de aplicación web predeterminado y seleccione los valores de Suscripción, Grupo de recursos y Plan de App Service.

  4. Seleccione Crear.

  5. Anote la propiedad Dirección URL del sitio de la sección Resumen. Esta dirección URL es el punto de conexión de back-end que se utilizará más adelante en el tutorial.

  6. Seleccione Publicar.

Una vez completado el asistente, este publica la aplicación web ASP.NET en Azure y la abre en el explorador predeterminado. La aplicación se puede ver en Azure App Services.

La dirección URL usa el nombre de la aplicación web que especificó anteriormente, con el formato http://<app_name>.azurewebsites.net.

Actualización del código para el cliente de UWP

En esta sección, actualizará el código del proyecto que completó en el Tutorial: Envío de notificaciones a aplicaciones de Plataforma universal de Windows mediante Azure Notification Hubs. El proyecto ya debe estar asociado a la Tienda Windows. También debe estar configurado para usar el Centro de notificaciones. En esta sección, agregue código para llamar el nuevo back-end de WebAPI y usarlo para registrar y enviar notificaciones.

  1. En Visual Studio, abra la solución que creó en el Tutorial: Envío de notificaciones a aplicaciones de Plataforma universal de Windows mediante Azure Notification Hubs.

  2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto Universal Windows Platform (UWP) y, a continuación, haga clic en Administrar paquetes de NuGet.

  3. En el lado izquierdo, seleccione Examinar.

  4. En el cuadro Buscar, escriba Cliente http.

  5. En la lista de resultados, haga clic en System.Net.Httpy haga clic en Instalar. Complete la instalación.

  6. Nuevamente en el cuadro Buscar de NuGet, escriba Json.net. Instale el paquete Newtonsoft.json y cierre la ventana Administrador de paquetes NuGet.

  7. En el Explorador de soluciones, en el proyecto WindowsApp, haga doble clic en MainPage.xaml para abrirlo en el editor de Visual Studio.

  8. En el archivo MainPage.xaml, reemplace la sección <Grid> por el código siguiente: Este código agrega un cuadro de texto de nombre de usuario y contraseña con el que el usuario se autentica. También agrega cuadros de texto para el mensaje de notificación y la etiqueta de nombre de usuario que debería recibir la notificación:

    <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. En el Explorador de soluciones, abra el archivo MainPage.xaml.cs de los proyectos (Windows 8.1) y (Windows Phone 8.1) . Agregue las siguientes instrucciones using en la parte superior de ambos archivos:

    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. En MainPage.xaml.cs del proyecto WindowsApp, agregue el siguiente miembro a la clase MainPage. Asegúrese de reemplazar <Enter Your Backend Endpoint> por el punto de conexión del back-end obtenido anteriormente. Por ejemplo, http://mybackend.azurewebsites.net.

    private static string BACKEND_ENDPOINT = "<Enter Your Backend Endpoint>";
    
  11. Agregue el código siguiente a la clase MainPage en MainPage.xaml.cs para los proyectos (Windows 8.1) y (Windows Phone 8.1) .

    El método PushClick es el controlador de clics para el botón Enviar inserción . Llama al back-end para desencadenar una notificación a todos los dispositivos con una etiqueta de nombre de usuario que coincida con el parámetro to_tag . El mensaje de notificación se envía como contenido JSON en el cuerpo de la solicitud.

    El método LoginAndRegisterClick es el controlador de clics del botón Login and register (Iniciar sesión y registrarse). Almacena el token de autenticación básico (representa cualquier token que usa el esquema de autenticación) localmente y después usa RegisterClient para registrar las notificaciones que usan el 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 y encuentre la llamada a InitNotificationsAsync() en el controlador de eventos OnLaunched(). Marque como comentario o elimine la llamada a InitNotificationsAsync(). El controlador del botón inicializa los registros de notificaciones:

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        //InitNotificationsAsync();
    
  13. Haga clic con el botón derecho en el proyecto WindowsApp, haga clic en Agregar y, después, en Clase. Asigne un nombre a la clase RegisterClient.cs y, luego, haga clic en Aceptar para generar la clase.

    Esta clase contiene las llamadas REST requeridas para ponerse en contacto con el back-end de la aplicación con la finalidad de registrarlas para las notificaciones push. También almacena localmente los identificadores registrationIds creados por el Centro de notificaciones, como se detalla en la sección Administración de registros desde un back-end. Usa un token de autorización almacenado localmente cuando hace clic en el botón Login and register (Iniciar sesión y registrarse).

  14. Agregue las siguientes instrucciones using en la parte superior del archivo 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. Agregue el siguiente código a la definición de clase RegisterClient:

    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 todos los cambios.

Prueba de la aplicación

  1. Inicie la aplicación en ambas versiones de Windows.

  2. Especifique un nombre de usuario y una contraseña, tal como se muestra en la pantalla siguiente. Debe diferir del nombre de usuario y contraseña que escriba en Windows Phone.

  3. Haga clic en Iniciar sesión y registrarse y compruebe que el cuadro de diálogo se muestre que ha iniciado sesión. Este código también habilita el botón Send Push (Enviar inserción).

    Captura de pantalla de la aplicación Notification Hubs que muestra el nombre de usuario y la contraseña rellenados.

  4. Después, en el campo Recipient Username Tag (Etiqueta de nombre de usuario destinatario), especifique el nombre de usuario registrado. Escriba un mensaje de notificación y haga clic en Enviar inserción.

  5. Solo los dispositivos que se han registrado con la etiqueta de nombre de usuario coincidente reciben el mensaje de notificación.

    Captura de pantalla de la aplicación Notification Hubs que muestra el mensaje que se ha insertado.

Pasos siguientes

En este tutorial, ha aprendido a enviar notificaciones push a usuarios concretos que tienen etiquetas asociadas a sus registros. Para aprender a enviar notificaciones push en función de la ubicación, pase al tutorial siguiente: