Share via


Inscription à partir de votre serveur principal d’application

Comme mentionné dans les sections précédentes, les appareils doivent créer une ou plusieurs inscriptions dans un hub de notification pour recevoir des notifications Push. Une façon de terminer cette inscription consiste à faire en sorte que les appareils mobiles contactent directement le hub de notification pour spécifier (ou mettre à jour) leur handle PNS et leurs balises. Cette approche présente un certain nombre de limitations et il existe certains scénarios dans lesquels il est conseillé de contacter votre propre serveur principal d’application lorsqu’un appareil actualise son inscription. Le serveur principal appelle ensuite le hub de notification.

Quand s’inscrire à partir de votre back-end d’application

Il existe deux scénarios dans lesquels il est recommandé de router les inscriptions d’appareils via votre back-end d’application.

Les balises doivent être sécurisées

Lorsqu’un appareil s’inscrit directement auprès d’un hub de notification, il peut spécifier n’importe quelle balise souhaitée. Ce n’est pas un problème si les balises sont des groupes d’intérêt public auxquels n’importe quel appareil peut s’abonner (par exemple, des flux d’actualités concernant les équipes sportives). Toutefois, il peut s’agir d’un problème lorsque certaines balises sont disponibles uniquement pour certains utilisateurs.

Pour inscrire chaque utilisateur uniquement aux balises autorisées, vous devez acheminer les opérations d’inscription via votre propre serveur principal d’application, qui peut effectuer l’authentification de l’utilisateur et autoriser l’inscription pour les balises requises.

L’exemple le plus courant de ce scénario consiste à utiliser des balises pour représenter les ID utilisateur. Dans ce cas, vous souhaitez empêcher les appareils de s’inscrire aux étiquettes qui représentent d’autres utilisateurs, car ils recevront les notifications de cet autre utilisateur.

Les balises sont modifiées par votre back-end d’application

L’inscription à partir de l’appareil est pratique et vous permet de configurer rapidement des notifications Push et un routage enrichi vers des groupes d’intérêt. Toutefois, l’inscription à partir de l’appareil ne fonctionne pas très bien si vous souhaitez modifier des balises suite à des événements qui se produisent sur d’autres appareils.

Envisagez deux scénarios : si les balises sur le téléphone d’Alice sont définies suite à des événements se produisant sur le téléphone d’Alice, il est facile pour l’application de mettre à jour les étiquettes dans le hub de notification. Si, d’un autre côté, les balises doivent changer en raison d’événements qui se produisent sur d’autres appareils (par exemple, l’ordinateur portable d’Alice lors de la connexion à un site web), l’appareil doit attendre que l’application soit à nouveau active afin de refléter les modifications dans le hub de notification.

Un exemple spécifique du scénario précédent est une application musicale qui inclut une expérience web et une application mobile. Dans ce cas, un utilisateur spécifique peut suivre une nouvelle bande via le site web et souhaiter que l’appareil commence à recevoir des notifications sur la nouvelle bande dès que possible. Un autre exemple est le moment où les balises proviennent d’autres parties de votre back-end (un CRM, par exemple), qui peuvent changer l’état de l’utilisateur de Silver à Gold. Cette modification peut entraîner la définition d’une nouvelle balise sur toutes les inscriptions des utilisateurs.

Guide pratique pour s’inscrire à partir du serveur principal

Lors de l’inscription d’un appareil, un hub de notification doit faire la distinction entre différents appareils. Cela ne peut pas être accompli uniquement en examinant les handles PNS, car ils sont temporaires et non uniques. Pour résoudre ce problème, Notification Hubs génère des ID d’inscription de longue durée que chaque appareil doit stocker localement afin de pouvoir faire référence à sa propre inscription chaque fois qu’il met à jour son handle PNS, ses balises ou son modèle.

La figure suivante montre le flux d’inscription pour les notifications natives :

  1. Sur l’appareil, si aucun ID d’inscription n’est stocké localement,

    1. Appelez le serveur principal de l’application pour obtenir l’ID d’inscription.

    2. Le serveur principal de l’application appelle des hubs de notification pour créer un ID d’inscription, puis retourne l’ID à l’appareil.

    3. Stockez l’ID d’inscription dans le stockage local de l’appareil.

  2. Sur l’appareil, récupérez l’ID d’inscription à partir du stockage local :

    1. Appelez le serveur principal de l’application, en fournissant l’ID d’inscription, le handle PNS et les balises.

    2. Le serveur principal d’application crée ou met à jour l’inscription correspondante sur le hub de notification.

    3. Si le serveur principal de l’application retourne le code d’état 410, un nouvel ID d’inscription doit être créé. Supprimez l’ID d’inscription du stockage local et redémarrez à l’étape 1.

Backend Registration

Le flux des notifications de modèle est analogue. Les seules différences sont les suivantes :

  1. Si un appareil utilise plusieurs modèles, il doit stocker un ID d’inscription par modèle.

  2. Vous pouvez identifier les modèles à l’aide de la propriété TemplateName de l’inscription.

Le code suivant est un exemple de points de terminaison principaux.

public class RegisterController : ApiController
    {

        private NotificationHubClient hub;

        public RegisterController()
        {
            hub = NotificationHubClient.CreateClientFromConnectionString("Endpoint=sb://buildhub-ns.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=DuWV4SQ08poV6HZly8O/KQNWv3YRTZlExJxu3pNCjGU=", "build2014_2");
        }
        
        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()
        {
            return await hub.CreateRegistrationIdAsync();
        }

        // PUT api/register/5
        // This creates or updates a registration (with provided PNS handle) at the specified id
        public async void Put(string id, DeviceRegistration deviceUpdate)
        {
            // IMPORTANT: add logic to make sure that caller is allowed to register for the provided tags
            
            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 "gcm":
                    registration = new GcmRegistrationDescription(deviceUpdate.Handle);
                    break;
                default:
                    throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            registration.RegistrationId = id;
            registration.Tags = new HashSet<string>(deviceUpdate.Tags);

            try
            {
                await hub.CreateOrUpdateRegistrationAsync(registration);
            } catch (MessagingException e) {
                ReturnGoneIfHubResponseIsGone(e);
            }
        }

        // DELETE api/register/5
        public async void Delete(string id)
        {
            await hub.DeleteRegistrationAsync(id);
        }


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

Notez que dans le code précédent, vous devez ajouter la logique pour vous assurer que le client appelant ce point de terminaison est autorisé à s’inscrire aux balises demandées. En outre, votre back-end peut ajouter les balises elle-même (par exemple, une balise userid ).

L’exemple de code suivant montre comment implémenter la méthode d’inscription pour une application Windows Store, à partir de l’appareil, avec les points de terminaison précédents :

class RegisterClient
    {
        private string POST_URL = "{your back-end endpoints}";

        private class DeviceRegistration
        {
            public string Platform { get; set; }
            public string Handle { get; set; }
            public string[] Tags { get; set; }
        }

        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)
            {
                // log or throw
            }
        }

        private async Task<HttpStatusCode> UpdateRegistrationAsync(string regId, DeviceRegistration deviceRegistration)
        {
            using (var httpClient = new HttpClient())
            {
                var putUri = POST_URL + "/" + regId;
                var response = await httpClient.PutAsJsonAsync<DeviceRegistration>(putUri, deviceRegistration);
                return response.StatusCode;
            }
        }

        private async Task<string> RetrieveRegistrationIdOrRequestNewOneAsync()
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            if (!settings.ContainsKey("__NHRegistrationId"))
            {
                using (var httpClient = new HttpClient())
                {
                    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 Exception();
                    }
                }
            }
            return (string)settings["__NHRegistrationId"];

        }
    }

Stockage des ID d’inscription dans une base de données back-end

Parfois, les applications souhaitent conserver les ID d’inscription dans le serveur principal de l’application au lieu du stockage local de l’appareil. Cela se produit généralement lorsque le serveur principal de l’application a déjà un moyen d’identifier les appareils (par exemple, un id d’installation) et un moyen de stocker des informations sur l’appareil sur le stockage principal (par exemple, lors de la migration à partir d’une solution push personnalisée dans laquelle les handles PNS ont été stockés).

Comment modifier des étiquettes à partir du back-end

Si vous souhaitez modifier des étiquettes à partir du back-end, vous devez disposer d’un moyen pour le back-end d’identifier les inscriptions à modifier. Cette opération est généralement effectuée à l’aide d’une balise.

Par exemple, supposons qu’il existe une application de musique dans laquelle un utilisateur ajoute un nouveau groupe favori à partir du web, et que le serveur principal ajoute une balise dans les inscriptions mobiles de l’utilisateur en conséquence. Dans ce cas, l’application utilise une balise pour identifier l’utilisateur, puis utilise cette balise pour récupérer les inscriptions à mettre à jour et les mettre à jour.

L’exemple de code suivant récupère les inscriptions et y ajoute une nouvelle balise.

var registrations = await hub.GetRegistrationsByTagAsync("{userId}", 10);
            foreach (var reg in registrations)
            {
                reg.Tags.Add("{newBand}");
                await hub.UpdateRegistrationAsync(reg);
            }

Notez que dans cet exemple, si vous utilisez des modèles, nous partons du principe que vous ajoutez la balise sur tous vos modèles.