Guida all'architettura push aziendaleEnterprise push architectural guidance

Al giorno d'oggi, le aziende stanno gradualmente passando alla creazione di applicazioni per dispositivi mobili sia per gli utenti finali (esterni) che per i dipendenti (interni).Enterprises today are gradually moving towards creating mobile applications for either their end users (external) or for the employees (internal). Le aziende dispongono di sistemi back-end già esistenti, ovvero mainframe o applicazioni LoB che è necessario integrare nell'architettura delle applicazioni per dispositivi mobili.They have existing backend systems in place be it mainframes or some LoB applications which must be integrated into the mobile application architecture. In questa Guida verrà illustrato come eseguire questa integrazione nel modo migliore possibile, fornendo possibili soluzioni per scenari comuni.This guide will talk about how best to do this integration recommending possible solution to common scenarios.

Una richiesta frequente riguarda l'invio di notifiche push agli utenti tramite l'applicazione per dispositivi mobili in uso quando si verifica un evento di interesse nei sistemi back-end.A frequent requirement is for sending push notification to the users through their mobile application when an event of interest occurs in the backend systems. Ad esempio,E.g. una cliente di una banca ha installato sul proprio iPhone l'app dei servizi bancari della banca stessa e desidera ricevere una notifica quando sul conto viene effettuato un addebito superiore a un determinato importo. Oppure, in uno scenario intranet, un dipendente del reparto finanziario ha installato sul proprio Windows Phone una app per l'approvazione dei budget e desidera ricevere una notifica quando gli viene inviata una richiesta di approvazione.a bank customer who has the bank's banking app on her iPhone wants to be notified when a debit is made above a certain amount from her account or an intranet scenario where an employee from finance department who has a budget approval app on his Windows Phone wants to be notified when he gets an approval request.

È probabile che l'elaborazione del conto o dell'approvazione venga eseguita in un qualche sistema back-end che deve avviare un'operazione push verso l'utente.The bank account or approval processing is likely to be done in some backend system which must initiate a push to the user. È possibile che siano presenti diversi sistemi back-end che devono eseguire la stessa tipologia di logica per implementare un push quando un evento attiva una notifica.There may be multiple such backend systems which must all build the same kind of logic to implement push when an event triggers a notification. In questo caso la complessità è dovuta alla necessità di integrare numerosi back-end con un singolo sistema di push, dove gli utenti finali possono aver eseguito la sottoscrizione a diverse notifiche e dove possono essere usate più applicazioni mobili, ad esempio nel caso di applicazioni per dispositivi mobili intranet che possono ricevere notifiche da diversi sistemi back-end.The complexity here lies in integrating several backend systems together with a single push system where the end users may have subscribed to different notifications and there may even be multiple mobile applications e.g. in the case of intranet mobile apps where one mobile application may want to receive notifications from multiple such backend systems. I sistemi back-end non conoscono o non hanno necessità di conoscere la semantica e/o la tecnologia di push. Per questo motivo, una soluzione comunemente usata fino ad ora consiste nell'introdurre un componente che esegue il polling dei sistemi back-end per qualsiasi evento di interesse ed è responsabile dell'invio di messaggi push al client.The backend systems do not know or need to know of push semantics/technology so a common solution here traditionally has been to introduce a component which polls the backend systems for any events of interest and is responsible for sending the push messages to the client. Di seguito viene descritta una soluzione ancora migliore che prevede l'uso del modello Bus di servizio di Azure - Argomento/Sottoscrizione. Tale modello, infatti, riduce la complessità della soluzione e la rende scalabile.Here we will talk about an even better solution using Azure Service Bus - Topic/Subscription model which will reduce the complexity while making the solution scalable.

Di seguito è descritta l'architettura generale della soluzione, descritta con numerose app per dispositivi mobili ma ugualmente applicabile nel caso in cui ne venga usata una soltanto.Here is the general architecture of the solution (generalized with multiple mobile apps but equally applicable when there is only one mobile app)

ArchitetturaArchitecture

L'elemento chiave di questo diagramma dell'architettura è il bus di servizio di Azure, che fornisce un modello di programmazione di tipo argomenti/sottoscrizioni. Per altre informazioni su tale modello, vedere Come usare gli argomenti e le sottoscrizioni del bus di servizio.The key piece in this architectural diagram is Azure Service Bus which provides a topics/subscriptions programming model (more on it at [Service Bus Pub/Sub programming]). Il ricevitore, in questo caso il back-end Mobile (in genere Servizi mobili di Azure, che avvia un'operazione push alle app per dispositivi mobili), non riceve messaggi direttamente dai sistemi back-end. È disponibile invece un livello di astrazione intermedio fornito dal bus di servizio di Azure che consente al back-end Mobile di ricevere messaggi da uno o più sistemi back-end.The receiver, which in this case, is the Mobile backend (typically [Azure Mobile Service], which will initiate a push to the mobile apps) does not receive messages directly from the backend systems but instead we have an intermediate abstraction layer provided by [Azure Service Bus] which enables mobile backend to receive messages from one or more backend systems. È necessario creare un argomento del bus di servizio per ciascuno dei sistemi back-end, ad esempio Contabilità, Risorse umane e Finanza. Si tratta fondamentalmente di "argomenti" rilevanti che danno luogo a messaggi da inviare come notifiche push.A Service Bus Topic needs to be created for each of the backend systems e.g. Account, HR, Finance which are basically "topics" of interest which will initiate messages to be sent as push notification. I sistemi back-end invieranno messaggi a questi argomenti.The backend systems will send messages to these topics. Un back-end Mobile può sottoscrivere uno o più di tali argomenti creando una sottoscrizione del bus di servizio.A Mobile Backend can subscribe to one or more such topics by creating a Service Bus subscription. Questo autorizza il back-end Mobile a ricevere una notifica dal sistema back-end corrispondente.This will entitle the mobile backend to receive a notification from the corresponding backend system. Il back-end Mobile continua a rimanere in ascolto per rilevare i messaggi inviati alla sottoscrizione e, non appena ne arriva uno, lo invia come notifica all'hub di notifica.Mobile backend continues to listen for messages on their subscriptions and as soon as a message arrives, it turns back and sends it as notification to its notification hub. L'hub di notifica invia infine il messaggio all'app per dispositivi mobili.Notification hubs then eventually delivers the message to the mobile app. Di seguito sono riepilogati i componenti chiave:So to summarize the key components, we have:

  1. Sistema back-end (sistemi LoB/legacy)Backend systems (LoB/Legacy systems)
    • Crea un argomento del bus di servizioCreates Service Bus Topic
    • Invia un messaggioSends Message
  2. Back-end MobileMobile backend
    • Crea una sottoscrizione al servizioCreates Service Subscription
    • Riceve un messaggio (dal sistema back-end)Receives Message (from Backend system)
    • Invia la notifica al client (tramite Hub di notifica di Azure)Sends notification to clients (via Azure Notification Hub)
  3. Applicazione per dispositivi mobiliMobile Application
    • Riceve e visualizza la notificaReceives and display notification

Vantaggi:Benefits:

  1. Il disaccoppiamento tra il ricevitore (app/servizio per dispositivi mobili tramite Hub di notifica) e il mittente(sistemi back-end) consente l'integrazione di sistemi back-end aggiuntivi con modifiche minime.The decoupling between the receiver (mobile app/service via Notification Hub) and sender (backend systems) enables additional backend systems being integrated with minimal change.
  2. In questo modo, è possibile ricevere eventi da uno o più sistemi back-end anche nello scenario con più app per dispositivi mobili.This also makes the scenario of multiple mobile apps being able to receive events from one or more backend systems.

Esempio:Sample:

PrerequisitiPrerequisites

È necessario completare le seguenti esercitazioni per acquisire familiarità con i concetti e con i comuni passaggi di creazione e configurazione:You should complete the following tutorials to familiarize with the concepts as well as common creation & configuration steps:

  1. Come usare gli argomenti e le sottoscrizioni del bus di servizio: viene illustrato nei dettagli l'utilizzo di argomenti/sottoscrizioni del bus di servizio. Viene inoltre mostrato come creare uno spazio dei nomi per contenere argomenti/sottoscrizioni e come inviare e ricevere messaggi da questi ultimi.[Service Bus Pub/Sub programming] - This explains the details of working with Service Bus Topics/Subscriptions, how to create a namespace to contain topics/subscriptions, how to send & receive messages from them.
  2. Introduzione ad Hub di notifica - Esercitazione per Windows Universal : illustra come configurare un'app di Windows Store e usare Hub di notifica per registrare e quindi ricevere le notifiche.[Notification Hubs - Windows Universal tutorial] - This explains how to set up a Windows Store app and use Notification Hubs to register and then receive notifications.

Codice di esempioSample code

Il codice completo è disponibile nella pagina relativa agli esempi di Hub di notifica.The full sample code is available at [Notification Hub Samples]. Il codice è suddiviso in tre componenti:It is split into three components:

  1. EnterprisePushBackendSystemEnterprisePushBackendSystem

    a.a. Il progetto usa il pacchetto NuGet WindowsAzure.ServiceBus ed è basato su quanto riportato in Come usare gli argomenti e le sottoscrizioni del bus di servizio.This project uses the WindowsAzure.ServiceBus Nuget package and is based on [Service Bus Pub/Sub programming].

    b.b. Si tratta di una app console C# per simulare un sistema LoB che avvia il messaggio da recapitare all'app per dispositivi mobili.This is a simple C# console app to simulate an LoB system which initiates the message to be delivered to the mobile app.

     static void Main(string[] args)
     {
         string connectionString =
             CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
    
         // Create the topic where we will send notifications
         CreateTopic(connectionString);
    
         // Send message
         SendMessage(connectionString);
     }
    

    c.c. CreateTopic viene usato per creare l'argomento del bus di servizio a cui verranno inviati i messaggi.CreateTopic is used to create the Service Bus topic where we will send messages.

     public static void CreateTopic(string connectionString)
     {
         // Create the topic if it does not exist already
    
         var namespaceManager =
             NamespaceManager.CreateFromConnectionString(connectionString);
    
         if (!namespaceManager.TopicExists(sampleTopic))
         {
             namespaceManager.CreateTopic(sampleTopic);
         }
     }
    

    d.d. SendMessage viene usato per inviare i messaggi a questo argomento del bus di servizio.SendMessage is used to send the messages to this Service Bus Topic. Ai fini dell'esempio, viene semplicemente inviato, a cadenza periodica, un insieme di messaggi casuali all'argomento.Here we are simply sending a set of random messages to the topic periodically for the purpose of the sample. Nella realtà, sarebbe presente un sistema back-end che invia i messaggi quando si verifica un evento.Normally there will be a backend system which will send messages when an event occurs.

     public static void SendMessage(string connectionString)
     {
         TopicClient client =
             TopicClient.CreateFromConnectionString(connectionString, sampleTopic);
    
         // 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
             BrokeredMessage message = new BrokeredMessage(notification);
             client.Send(message);
    
             Console.WriteLine("{0} Message sent - '{1}'", DateTime.Now, notification);
    
             System.Threading.Thread.Sleep(new TimeSpan(0, 0, 10));
         }
     }
    
  2. ReceiveAndSendNotificationReceiveAndSendNotification

    a.a. Il progetto usa i pacchetti NuGet WindowsAzure.ServiceBus e Microsoft.Web.WebJobs.Publish ed è basato su quanto riportato in Come usare gli argomenti e le sottoscrizioni del bus di servizio.This project uses the WindowsAzure.ServiceBus and Microsoft.Web.WebJobs.Publish Nuget packages and is based on [Service Bus Pub/Sub programming].

    b.b. Si tratta di un'altra app console C# che verrà eseguita come processo Web di Azure. Questa app deve infatti essere eseguita continuamente per ascoltare i messaggi dei sistemi LOB/back-end.This is another C# console app which we will run as an [Azure WebJob] since it has to run continuously to listen for messages from the LoB/backend systems. L'app sarà parte del back-end Mobile.This will be part of your Mobile backend.

     static void Main(string[] args)
     {
         string connectionString =
                  CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
    
         // Create the subscription which will receive messages
         CreateSubscription(connectionString);
    
         // Receive message
         ReceiveMessageAndSendNotification(connectionString);
     }
    

    c.c. CreateSubscription viene usato per creare una sottoscrizione del bus di servizio per l'argomento in cui il sistema back-end invierà i messaggi.CreateSubscription is used to create a Service Bus subscription for the topic where the backend system will send messages. A seconda dello scenario aziendale, questo argomento crea una o più sottoscrizioni agli argomenti corrispondenti. Può, ad esempio, ricevere messaggi dal sistema Risorse umane, dal sistema Finanza e così via.Depending on the business scenario, this component will create one or more subscriptions to corresponding topics (e.g. some may be receiving messages from HR system, some from Finance system, and so on)

     static void CreateSubscription(string connectionString)
     {
         // Create the subscription if it does not exist already
         var namespaceManager =
             NamespaceManager.CreateFromConnectionString(connectionString);
    
         if (!namespaceManager.SubscriptionExists(sampleTopic, sampleSubscription))
         {
             namespaceManager.CreateSubscription(sampleTopic, sampleSubscription);
         }
     }
    

    d.d. ReceiveMessageAndSendNotification viene usato per leggere il messaggio inviato dall'argomento usando la relativa sottoscrizione. Se l'operazione di lettura ha esito positivo, viene creata una notifica (nello scenario di esempio una notifica di tipo avviso popup nativo di Windows) da inviare all'applicazione mobile tramite gli hub di notifica di Windows.ReceiveMessageAndSendNotification is used to read the message from the topic using its subscription and if the read is successful then craft a notification (in the sample scenario a Windows native toast notification) to be sent to the mobile application using Azure Notification Hubs.

     static void ReceiveMessageAndSendNotification(string connectionString)
     {
         // Initialize the Notification Hub
         string hubConnectionString = CloudConfigurationManager.GetSetting
                 ("Microsoft.NotificationHub.ConnectionString");
         hub = NotificationHubClient.CreateClientFromConnectionString
                 (hubConnectionString, "enterprisepushservicehub");
    
         SubscriptionClient Client =
             SubscriptionClient.CreateFromConnectionString
                     (connectionString, sampleTopic, sampleSubscription);
    
         Client.Receive();
    
         // Continuously process messages received from the subscription
         while (true)
         {
             BrokeredMessage message = Client.Receive();
             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.GetBody<string>();
                     Console.WriteLine("Body: " + messageBody + "\n");
    
                     toastMessage = toastMessage.Replace("{messagepayload}", messageBody);
                     SendNotificationAsync(toastMessage);
    
                     // Remove message from subscription
                     message.Complete();
                 }
                 catch (Exception)
                 {
                     // Indicate a problem, unlock message in subscription
                     message.Abandon();
                 }
             }
         }
     }
     static async void SendNotificationAsync(string message)
     {
         await hub.SendWindowsNativeNotificationAsync(message);
     }
    

    e.e. Per pubblicare questo elemento come processo Web, in Visual Studio fare clic con il pulsante destro del mouse sulla soluzione e selezionare Pubblica come processo Web di AzureFor publishing this as a WebJob, right click on the solution in Visual Studio and select Publish as WebJob

    f.f. Selezionare il proprio profilo di pubblicazione e, se non è già presente, creare un nuovo sito Web di Azure che ospiterà questo processo Web, quindi fare clic su Pubblica.Select your publishing profile and create a new Azure WebSite if it doesnt exist already which will host this WebJob and once you have the WebSite then Publish.

    g.g. Configurare il processo per l'esecuzione continua, in modo che, quando si accede al portale di Azure classico , venga visualizzata una schermata simile alla seguente:Configure the job to be "Run Continuously" so that when you log in to the [Azure Classic Portal] you should see something like the following:

  3. EnterprisePushMobileAppEnterprisePushMobileApp

    a.a. Si tratta di un'applicazione Windows Store che riceve notifiche di tipo avviso popup dal processo Web in esecuzione come parte del back-end Mobile e le visualizza.This is a Windows Store application which will receive toast notifications from the WebJob running as part of your Mobile backend and display it. Si basa su quanto riportato in Introduzione ad Hub di notifica - Esercitazione per Windows Universal.This is based on [Notification Hubs - Windows Universal tutorial].

    b.b. Verificare che l'applicazione sia abilitata alla ricezione di notifiche di tipo avviso popup.Ensure that your application is enabled to receive toast notifications.

    c.c. Assicurarsi che all'avvio dell'app, dopo aver sostituito HubName e DefaultListenSharedAccessSignature, venga chiamato il seguente codice di registrazione di Hub di notifica:Ensure that the following Notification Hubs registration code is being called at the App start up (after replacing the HubName and 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();
         }
     }
    

Esecuzione di esempio:Running sample:

  1. Assicurarsi che il processo Web venga eseguito correttamente e che sia pianificato per l'esecuzione continua.Ensure that your WebJob is running successfully and scheduled to "Run Continuously".
  2. Eseguire EnterprisePushMobileApp che avvierà l'app di Windows Store.Run the EnterprisePushMobileApp which will start the Windows Store app.
  3. Eseguire l'applicazione console EnterprisePushBackendSystem che simula il back-end LOB e avvia l'invio di messaggi. Verranno visualizzate notifiche di tipo avviso popup simili alle seguenti:Run the EnterprisePushBackendSystem console application which will simulate the LoB backend and will start sending messages and you should see toast notifications appearing like the following:

  4. All'inizio i messaggi sono stati inviati ad argomenti del bus di servizio, operazione monitorata da sottoscrizioni del bus di servizio nel processo Web.The messages were originally sent to Service Bus topics which was being monitored by Service Bus subscriptions in your Web Job. Una volta ricevuto un messaggio, è stata creata una notifica che è stata inviata all'app per dispositivi mobili.Once a message was received, a notification was created and sent to the mobile app. Per confermare l'elaborazione, è possibile esaminare i log del processo Web, selezionando il collegamento Log in relazione al processo Web nel portale di Azure classico :You can look through the WebJob logs to confirm the processing when you go to the Logs link in [Azure Classic Portal] for your Web Job: