Guide architectural des notifications Push d’entreprise

Les entreprises se tournent aujourd’hui progressivement vers la création d’applications mobiles pour leurs clients (externes) ou leurs collaborateurs (internes). Ils disposent de systèmes principaux, qu’il s’agisse de grands systèmes ou de certaines applications métiers, qui doivent être intégrés à l’architecture de l’application mobile. Ce guide vous présente comment réussir au mieux cette intégration, en recommandant des solutions possibles pour les scénarios habituels.

Une exigence fréquente est l’envoi de notifications Push aux utilisateurs via leurs applications mobiles, lorsqu’un événement se produit dans les systèmes principaux. Par exemple, un client d’une banque disposant d’une application bancaire sur un iPhone souhaite être averti lorsque son compte est débité d’un montant supérieur à un seuil défini ou un scénario intranet dans lequel un employé du service financier disposant d’une application d’approbation du budget sur un téléphone Windows Phone souhaite être averti lorsqu’il reçoit une demande d’approbation.

Le traitement des comptes bancaires ou des approbations est généralement effectué dans un système principal, qui doit envoyer une notification Push à l’utilisateur. Il peut y avoir plusieurs systèmes principaux qui doivent tous générer le même genre de logique afin d’envoyer une notification Push lorsqu’un événement la déclenche. Ici, la complexité réside dans l’intégration de plusieurs systèmes principaux avec un système Push unique où les utilisateurs peuvent être abonnés à différentes notifications et même peut-être à plusieurs applications mobiles, Par exemple, dans le cas d’applications mobiles intranet où une application mobile peut recevoir des notifications à partir de plusieurs systèmes principaux. Les systèmes principaux n’ont pas besoin de connaître une technologie ou une sémantique Push. Une solution courante a donc généralement été d’introduire un composant qui interroge les systèmes principaux pour tout événement vous intéressant et qui est chargé d’envoyer les messages Push au client.

Une solution encore plus efficace consiste à utiliser le modèle Azure Service Bus - Rubrique/abonnement, qui réduit la complexité tout en rendant la solution évolutive.

Voici l’architecture générale de la solution (généralisée pour plusieurs applications mobiles mais également applicable lorsqu’il n’y a qu’une seule application mobile)

Architecture

Diagram of the enterprise architecture showing the flow through Events, Subscriptions, and Push Messages.

L'élément clé de ce diagramme architectural est Azure Service Bus, qui fournit un modèle de programmation des rubriques/abonnements (la page Programmation Service Bus Pub/Subapporte plus d'informations à ce sujet). Le récepteur, dans ce cas le serveur principal Mobile (généralement Azure Mobile Service, qui initie une transmission de type push vers les applications mobiles), ne reçoit pas directement les messages des systèmes principaux mais d'une couche d'abstraction intermédiaire fournie par Azure Service Bus qui permet au serveur principal Mobile de recevoir des messages d'un ou plusieurs systèmes principaux. Une rubrique Service Bus doit être créée pour chacun des systèmes principaux, par exemple Comptabilité, RH, Finance, qui sont essentiellement des « rubriques » d’intérêt qui génèrent des messages à envoyer en tant que notification Push. Les systèmes principaux envoient les messages à ces rubriques. Un service principal Mobile peut s’abonner à une ou plusieurs de ces rubriques en créant un abonnement Service Bus. Cela autorise le serveur principal mobile à recevoir une notification du système principal correspondant. Le serveur principal mobile continue à écouter les messages sur ses abonnements et dès qu’un message arrive, il le reprend et l’envoie sous forme de notification à son hub de notification. Pour finir, les hubs de notification remettent ensuite le message à l’application mobile. Voici la liste des composants clés :

  1. les systèmes principaux (systèmes métiers/hérités)
    • Crée une rubrique Service Bus
    • Envoie un message
  2. Serveur principal mobile
    • Crée l’abonnement au service
    • Reçoit le message (du système principal)
    • Envoie une notification aux clients (via Azure Notification Hub)
  3. Application mobile
    • Reçoit et affiche une notification

Avantages

  1. Le découplage entre l’expéditeur (les systèmes principaux) et le récepteur (application/service mobile via Notification Hub) permet à des systèmes principaux supplémentaires d’être intégrés, et ce avec un minimum de modifications.
  2. Cela permet également à plusieurs applications mobiles de recevoir des événements à partir d’un ou plusieurs systèmes principaux.

Exemple

Prérequis

Complétez les tutoriels suivants pour vous familiariser avec les concepts et les étapes habituelles de création et de configuration :

  1. Programmation Service Bus Pub/Sub : ce tutoriel explique en détail comment utiliser des rubriques/abonnements Service Bus, comment créer un espace de noms pour contenir des rubriques/abonnements et comment envoyer et recevoir des messages à partir de ces rubriques/abonnements.
  2. Notification Hubs : didacticiel Windows Universal : ce tutoriel explique comment configurer une application Windows Store et Notification Hubs pour vous inscrire et recevoir des notifications.

Exemple de code

L'exemple de code complet est disponible dans la page Exemples de Notification Hub. Il est divisé en trois composants :

  1. EnterprisePushBackendSystem

    a. Ce projet utilise le package NuGet Azure.Messaging.ServiceBus. Il repose sur la programmation Service Bus Pub/Sub.

    b. Il s’agit d’une console d’application C# simple pour simuler un système métier qui lance le message à remettre à l’application mobile.

    static async Task Main(string[] args)
    {
        string connectionString =
            ConfigurationManager.AppSettings.Get("Azure.ServiceBus.ConnectionString");
    
        // Create the topic
        await CreateTopicAsync(connectionString);
    
        // Send message
        await SendMessageAsync(connectionString);
    }
    

    c. CreateTopicAsync est utilisé pour créer la rubrique Service Bus.

    public static async Task CreateTopicAsync(string connectionString)
    {
        // Create the topic if it does not exist already
        ServiceBusAdministrationClient client = new ServiceBusAdministrationClient(connectionString);
    
        if (!await client.TopicExistsAsync(topicName))
        {
            await client.CreateTopicAsync(topicName);
        }
    }
    

    d. SendMessageAsync est utilisé pour envoyer les messages à cette rubrique Service Bus. Ce code envoie simplement un ensemble de messages aléatoires à la rubrique. Normalement, un système principal envoie des messages lorsqu’un événement se produit.

    public static sync Task SendMessageAsync(string connectionString)
    {
        await using var client = new ServiceBusClient(connectionString);
        ServiceBusSender sender = client.CreateSender(topicName);
    
        // Sends random messages every 10 seconds to the topic
        string[] messages =
        {
            "Employee Id '{0}' has joined.",
            "Employee Id '{0}' has left.",
            "Employee Id '{0}' has switched to a different team."
        };
    
        while (true)
        {
            Random rnd = new Random();
            string employeeId = rnd.Next(10000, 99999).ToString();
            string notification = String.Format(messages[rnd.Next(0,messages.Length)], employeeId);
    
            // Send Notification
            ServiceBusMessage message = new ServiceBusMessage(notification);
            await sender.SendMessageAsync(message);
    
            Console.WriteLine("{0} Message sent - '{1}'", DateTime.Now, notification);
    
            System.Threading.Thread.Sleep(new TimeSpan(0, 0, 10));
        }
    }
    
  2. ReceiveAndSendNotification

    a. Ce projet utilise les packages NuGet Azure.Messaging.ServiceBus et Microsoft.Web.WebJobs.Publish. Il repose sur la programmation Service Bus Pub/Sub.

    b. L’application de console suivante s'exécute comme une tâche web Azure, étant donné qu'elle doit s'exécuter en continu pour écouter les messages des systèmes métiers/principaux. Cette application fait partie de votre serveur principal Mobile.

    static async Task Main(string[] args)
    {
        string connectionString =
                 ConfigurationManager.AppSettings.Get("Azure.ServiceBus.ConnectionString");
    
        // Create the subscription that receives messages
        await CreateSubscriptionAsync(connectionString);
    
        // Receive message
        await ReceiveMessageAndSendNotificationAsync(connectionString);
    }
    

    c. CreateSubscriptionAsync permet de créer un abonnement Service Bus pour la rubrique où le système principal envoie les messages. Selon le scénario commercial, ce composant crée un ou plusieurs abonnements aux rubriques correspondantes (par exemple, certains peuvent recevoir les messages du système de RH, du système des Finances, etc.)

    static async Task CreateSubscriptionAsync(string connectionString)
    {
        // Create the subscription if it does not exist already
        ServiceBusAdministrationClient client = new ServiceBusAdministrationClient(connectionString);
    
        if (!await client.SubscriptionExistsAsync(topicName, subscriptionName))
        {
            await client.CreateSubscriptionAsync(topicName, subscriptionName);
        }
    }
    

    d. ReceiveMessageAndSendNotificationAsync est utilisé pour lire le message à partir de la rubrique en utilisant son abonnement et, si la lecture aboutit, une notification est créée (dans notre exemple, il s'agit d'une notification toast native Windows) pour être envoyée à l'application mobile à l'aide d'Azure Notification Hubs.

    static async Task ReceiveMessageAndSendNotificationAsync(string connectionString)
    {
        // Initialize the Notification Hub
        string hubConnectionString = ConfigurationManager.AppSettings.Get
                ("Microsoft.NotificationHub.ConnectionString");
        hub = NotificationHubClient.CreateClientFromConnectionString
                (hubConnectionString, "enterprisepushservicehub");
    
        ServiceBusClient Client = new ServiceBusClient(connectionString);
        ServiceBusReceiver receiver = Client.CreateReceiver(topicName, subscriptionName);
    
        // Continuously process messages received from the subscription
        while (true)
        {
            ServiceBusReceivedMessage message = await receiver.ReceiveMessageAsync();
            var toastMessage = @"<toast><visual><binding template=""ToastText01""><text id=""1"">{messagepayload}</text></binding></visual></toast>";
    
            if (message != null)
            {
                try
                {
                    Console.WriteLine(message.MessageId);
                    Console.WriteLine(message.SequenceNumber);
                    string messageBody = message.Body.ToString();
                    Console.WriteLine("Body: " + messageBody + "\n");
    
                    toastMessage = toastMessage.Replace("{messagepayload}", messageBody);
                    SendNotificationAsync(toastMessage);
    
                    // Remove message from subscription
                    await receiver.CompleteMessageAsync(message);
                }
                catch (Exception)
                {
                    // Indicate a problem, unlock message in subscription
                    await receiver.AbandonMessageAsync(message);
                }
            }
        }
    }
    static async void SendNotificationAsync(string message)
    {
        await hub.SendWindowsNativeNotificationAsync(message);
    }
    

    e. Pour publier cette application sous forme de travail web, cliquez avec le bouton droit sur la solution dans Visual Studio et sélectionnez Publier en tant que travail web

    Screenshot of the right-click options being displayed with Publish as Azure WebJob outlined in red.

    f. Sélectionnez votre profil de publication et créez un site web Azure s’il n’existe pas déjà : il héberge ce travail web. Quand vous disposez du site web, utilisez Publier.

    Screenshot showing the workflow to create a site on Azure.

    Capture d’écran de la boîte de dialogue Publier le site Web avec l’option sites Web Microsoft Azure sélectionnée, une flèche verte pointant vers la boîte de dialogue Sélectionner un site Web existant avec la nouvelle option en rouge, et une flèche verte pointant vers la boîte de dialogue Créer un site sur Microsoft Azure avec le nom du site et les options de création présentées en rouge.

    g. Configurez le travail sur « Exécuter en continu ». Ainsi, quand vous vous connectez au Azure portal, vous devriez voir ce qui suit :

    Screenshot of the Azure Portal with the enterprise push backend webjobs displayed and the Name, Schedule, and Logs values outlined in red.

  3. EnterprisePushMobileApp

    a. Cette application est une application Windows Store qui reçoit des notifications toast du WebJob en cours d’exécution dans le cadre de votre serveur principal Mobile et les affiche. Ce code repose sur Notification Hubs : didacticiel Windows Universal.

    b. Assurez-vous que la réception des notifications toast est activée dans votre application.

    c. Assurez-vous que le code d'inscription Notification Hubs suivant est appelé au démarrage de l'application (après avoir remplacé les valeurs HubName et DefaultListenSharedAccessSignature :

    private async void InitNotificationsAsync()
    {
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
        var hub = new NotificationHub("[HubName]", "[DefaultListenSharedAccessSignature]");
        var result = await hub.RegisterNativeAsync(channel.Uri);
    
        // Displays the registration ID so you know it was successful
        if (result.RegistrationId != null)
        {
            var dialog = new MessageDialog("Registration successful: " + result.RegistrationId);
            dialog.Commands.Add(new UICommand("OK"));
            await dialog.ShowAsync();
        }
    }
    

Exécution de l’exemple

  1. Assurez-vous que votre WebJob est exécuté avec succès et planifié pour s’exécuter en continu.

  2. Exécutez EnterprisePushMobileApp, qui démarre l’application Windows Store.

  3. Exécutez l’application console EnterprisePushBackendSystem qui simule le serveur principal métier et envoie des messages. Vous devez voir apparaître des notifications toast similaires à l’image suivante :

    Screenshot of a console running the Enterprise Push Backend System app and the message that is sent by the app.

  4. Les messages ont été envoyés aux rubriques Service Bus qui ont été analysées par les abonnements Service Bus dans votre tâche Web. Lors de la réception d’un message, une notification a été créée et envoyée à l’application mobile. Vous pouvez consulter les journaux d’activité WebJob pour confirmer le traitement quand vous accédez au lien Journaux d’activité dans le Azure portal pour votre tâche Web :

    Screenshot of the Continuous WebJob Details dialog box with the message that is sent outlined in red.