Panoramica di Servizi notifica Push Windows (WNS)

I servizi di notifica push di Windows (WNS) consentono agli sviluppatori di terze parti di inviare aggiornamenti a popup, riquadri, badge e raw dal proprio servizio cloud. È quindi un meccanismo utile per distribuire nuovi aggiornamenti agli utenti in modo efficiente e affidabile.

Funzionamento

Il diagramma seguente mostra il flusso di dati completo per l'invio di una notifica push. Comporta i seguenti passaggi:

  1. La tua applicazione richiede un canale di notifica push a WNS.
  2. Windows chiede a WNS di creare un canale di notifica. Questo canale viene restituito al dispositivo chiamante sotto forma di Uniform Resource Identifier (URI).
  3. L'URI del canale di notifica viene restituito da WNS alla tua applicazione.
  4. La tua applicazione invia l'URI al tuo servizio cloud. Poi memorizzi l'URI sul tuo servizio cloud in modo da potervi accedere quando invii le notifiche. L'URI è un'interfaccia tra la tua applicazione e il tuo servizio; è tua responsabilità implementare questa interfaccia con standard web sicuri e protetti.
  5. Quando il tuo servizio cloud ha un aggiornamento da inviare, lo comunica a WNS utilizzando l'URI del canale. Questo avviene inviando una richiesta HTTP POST, che include il carico di notifica, tramite Secure Sockets Layer (SSL). Questo passaggio richiede l'autenticazione.
  6. WNS riceve la richiesta e inoltra la notifica al dispositivo appropriato.

wns data flow diagram for push notification

Registrare la tua applicazione e ricevere le credenziali per il servizio cloud

Prima di poter inviare notifiche utilizzando WNS, la tua app deve essere registrata nello Store Dashboard, come descritto qui.

Richiesta di un canale di notifica

Quando un'applicazione in grado di ricevere notifiche push viene eseguita, deve prima richiedere un canale di notifica attraverso il sito CreatePushNotificationChannelForApplicationAsync. Per una discussione completa e un esempio di codice, vedi Come richiedere, creare e salvare un canale di notifica. Questa API restituisce un URI di canale collegato in modo univoco all'applicazione chiamante e al suo riquadro, attraverso il quale è possibile inviare tutti i tipi di notifica.

Dopo aver creato con successo un URI di canale, l'app lo invia al suo servizio cloud, insieme a tutti i metadati specifici dell'app che devono essere associati a questo URI.

Note importanti

  • Non garantiamo che l'URI del canale di notifica di un'applicazione rimanga sempre lo stesso. Consigliamo che l'applicazione richieda un nuovo canale ogni volta che viene eseguita e che aggiorni il suo servizio quando l'URI cambia. Lo sviluppatore non deve mai modificare l'URI del canale e deve considerarlo come una stringa black-box. Al momento, gli URI dei canali scadono dopo 30 giorni. Se la tua app per Windows 10 rinnova periodicamente il suo canale in background, puoi scaricare l'esempio di Push e notifiche periodiche per Windows 8.1 e riutilizzare il suo codice sorgente e/o il modello che dimostra.
  • L'interfaccia tra il servizio cloud e l'applicazione client è implementata da te, lo sviluppatore. Ti consigliamo di sottoporre l'app a un processo di autenticazione con il proprio servizio e di trasmettere i dati su un protocollo sicuro come HTTPS.
  • È importante che il servizio cloud si assicuri sempre che l'URI del canale utilizzi il dominio "notify.windows.com". Il servizio non deve mai inviare notifiche a un canale su un altro dominio. Se il callback della tua applicazione viene compromesso, un malintenzionato potrebbe inviare un URI di canale per effettuare lo spoofing di WNS. Senza ispezionare il dominio, il tuo servizio cloud potrebbe potenzialmente rivelare informazioni a questo attaccante senza saperlo. Il sottodominio dell'URI del canale è soggetto a modifiche e non deve essere considerato quando si convalida l'URI del canale.
  • Se il tuo servizio cloud tenta di inviare una notifica a un canale scaduto, WNS restituirà il codice di risposta 410. In risposta a questo codice, il tuo servizio non dovrà più tentare di inviare notifiche a quell'URI.

Autenticare il servizio cloud

Per inviare una notifica, il servizio cloud deve essere autenticato tramite WNS. Il primo passo di questo processo avviene quando registri la tua applicazione nella Dashboard del Microsoft Store. Durante il processo di registrazione, la tua app riceve un identificatore di sicurezza del pacchetto (SID) e una chiave segreta. Queste informazioni vengono utilizzate dal tuo servizio cloud per autenticarsi con WNS.

Lo schema di autenticazione di WNS è implementato utilizzando il profilo delle credenziali client del protocollo OAuth 2.0 . Il servizio cloud si autentica con WNS fornendo le proprie credenziali (Package SID e chiave segreta). In cambio, riceve un token di accesso. Questo token di accesso consente a un servizio cloud di inviare una notifica. Il token è richiesto per ogni richiesta di notifica inviata al WNS.

Ad alto livello, la catena di informazioni è la seguente:

  1. Il servizio cloud invia le proprie credenziali a WNS tramite HTTPS seguendo il protocollo OAuth 2.0. Questo autentica il servizio con WNS.
  2. WNS restituisce un token di accesso se l'autenticazione ha avuto successo. Questo token di accesso viene utilizzato in tutte le richieste di notifica successive fino alla sua scadenza.

wns diagram for cloud service authentication

Nell'autenticazione con WNS, il servizio cloud invia una richiesta HTTP su Secure Sockets Layer (SSL). I parametri sono forniti nel formato "application/x-www-for-urlencoded". Inserisci il SID del tuo pacchetto nel campo "client_id" e la tua chiave segreta nel campo "client_secret", come mostrato nell'esempio seguente. Per i dettagli della sintassi, consulta il riferimento alla richiesta di token di accesso .

Nota

Questo è solo un esempio, non è un codice "taglia-e-incolla" che puoi utilizzare con successo nel tuo codice. 

 POST /accesstoken.srf HTTP/1.1
 Content-Type: application/x-www-form-urlencoded
 Host: https://login.live.com
 Content-Length: 211
 
 grant_type=client_credentials&client_id=ms-app%3a%2f%2fS-1-15-2-2972962901-2322836549-3722629029-1345238579-3987825745-2155616079-650196962&client_secret=Vex8L9WOFZuj95euaLrvSH7XyoDhLJc7&scope=notify.windows.com

Il WNS autentica il servizio cloud e, in caso di successo, invia una risposta di "200 OK". Il token di accesso viene restituito nei parametri inclusi nel corpo della risposta HTTP, utilizzando il tipo di media "application/json". Dopo che il tuo servizio ha ricevuto il token di accesso, sei pronto per inviare le notifiche.

L'esempio seguente mostra una risposta di autenticazione andata a buon fine, che include il token di accesso. Per i dettagli sulla sintassi, vedi Intestazioni di richiesta e risposta del servizio di notifica push.

 HTTP/1.1 200 OK   
 Cache-Control: no-store
 Content-Length: 422
 Content-Type: application/json
 
 {
     "access_token":"EgAcAQMAAAAALYAAY/c+Huwi3Fv4Ck10UrKNmtxRO6Njk2MgA=", 
     "token_type":"bearer"
 }

Note importanti

  • Il protocollo OAuth 2.0 supportato in questa procedura segue la versione draft V16.
  • La Request for Comments (RFC) di OAuth utilizza il termine "client" per riferirsi al servizio cloud.
  • Potrebbero esserci delle modifiche a questa procedura quando la bozza di OAuth sarà finalizzata.
  • Il token di accesso può essere riutilizzato per più richieste di notifica. Questo permette al servizio cloud di autenticarsi una sola volta per inviare molte notifiche. Tuttavia, quando il token di accesso scade, il servizio cloud deve autenticarsi nuovamente per ricevere un nuovo token di accesso.

Invio di una notifica

Utilizzando l'URI del canale, il servizio cloud può inviare una notifica ogni volta che ha un aggiornamento per l'utente.

Il token di accesso descritto sopra può essere riutilizzato per più richieste di notifica; il cloud server non è tenuto a richiedere un nuovo token di accesso per ogni notifica. Se il token di accesso è scaduto, la richiesta di notifica restituirà un errore. Ti consigliamo di non provare a inviare nuovamente la notifica più di una volta se il token di accesso viene rifiutato. Se riscontri questo errore, dovrai richiedere un nuovo token di accesso e inviare nuovamente la notifica. Per il codice di errore esatto, vedi Codici di risposta delle notifiche push.

  1. Il servizio cloud effettua un HTTP POST all'URI del canale. Questa richiesta deve essere effettuata tramite SSL e contiene le intestazioni necessarie e il payload della notifica. L'intestazione dell'autorizzazione deve includere il token di accesso acquisito per l'autorizzazione.

    Un esempio di richiesta è mostrato qui. Per i dettagli sulla sintassi, vedi Codici di risposta delle notifiche push.

    Per maggiori dettagli sulla composizione del payload di notifica, consulta Quickstart: Invio di una notifica push. Il payload di una notifica push di un riquadri, di un toast o di un badge viene fornito come contenuto XML che aderisce ai rispettivi schemi Adaptive tiles schema o Legacy tiles schema. Il payload di una notifica grezza non ha una struttura specificata. È strettamente definito dalle app.

     POST https://cloud.notify.windows.com/?token=AQE%bU%2fSjZOCvRjjpILow%3d%3d HTTP/1.1
     Content-Type: text/xml
     X-WNS-Type: wns/tile
     Authorization: Bearer EgAcAQMAAAAALYAAY/c+Huwi3Fv4Ck10UrKNmtxRO6Njk2MgA=
     Host: cloud.notify.windows.com
     Content-Length: 24
    
     <body>
     ....
    
  2. WNS risponde per indicare che la notifica è stata ricevuta e sarà consegnata alla prossima occasione disponibile. Tuttavia, WNS non fornisce una conferma end-to-end che la notifica sia stata ricevuta dal dispositivo o dall'applicazione.

Questo diagramma illustra il flusso di dati:

wns diagram for sending a notification

Note importanti

  • WNS non garantisce l'affidabilità o la latenza di una notifica.
  • Le notifiche non devono mai contenere dati riservati, sensibili o personali.
  • Per inviare una notifica, il servizio cloud deve prima autenticarsi con WNS e ricevere un token di accesso.
  • Un token di accesso consente a un servizio cloud di inviare notifiche solo alla singola applicazione per la quale è stato creato il token. Un token di accesso non può essere utilizzato per inviare notifiche a più app. Pertanto, se il tuo servizio cloud supporta più app, deve fornire il token di accesso corretto per l'app quando invia una notifica a ciascun canale URI.
  • Quando il dispositivo è offline, per impostazione predefinita WNS memorizza un tipo di notifica (riquadro, badge, toast) per ogni URI del canale e nessuna notifica grezza.
  • Negli scenari in cui il contenuto delle notifiche è personalizzato per l'utente, WNS raccomanda che il servizio cloud invii immediatamente gli aggiornamenti quando li riceve. Esempi di questo scenario sono gli aggiornamenti dei feed dei social media, gli inviti alla comunicazione istantanea, le notifiche di nuovi messaggi o gli avvisi. In alternativa, puoi avere scenari in cui lo stesso aggiornamento generico viene consegnato frequentemente a un ampio sottoinsieme di utenti; ad esempio, aggiornamenti sul meteo, sulle azioni e sulle notizie. Le linee guida WNS specificano che la frequenza di questi aggiornamenti deve essere al massimo di uno ogni 30 minuti. L'utente finale o il WNS possono ritenere abusivi aggiornamenti di routine più frequenti.
  • Windows Notification Platform mantiene una connessione dati periodica con WNS per mantenere il socket vivo e sano. Se non ci sono applicazioni che richiedono o utilizzano i canali di notifica, il socket non verrà creato.

Scadenza delle notifiche dei riquadri e dei badge

Per impostazione predefinita, le notifiche di riquadri e badge scadono tre giorni dopo essere state scaricate. Quando una notifica scade, il contenuto viene rimosso dal riquadro o dalla coda e non viene più mostrato all'utente. È una buona pratica impostare una scadenza (utilizzando un tempo che abbia senso per la tua applicazione) per tutte le notifiche di riquadri e badge, in modo che il contenuto del tuo riquadro non rimanga più a lungo di quanto sia rilevante. Un tempo di scadenza esplicito è essenziale per i contenuti con una durata di vita definita. Questo assicura anche la rimozione dei contenuti obsoleti se il tuo servizio cloud smette di inviare notifiche o se l'utente si disconnette dalla rete per un periodo prolungato.

Il tuo servizio cloud può impostare una scadenza per ogni notifica impostando l'intestazione HTTP X-WNS-TTL per specificare il tempo (in secondi) in cui la notifica rimarrà valida dopo l'invio. Per maggiori informazioni, vedi Intestazioni di richiesta e risposta del servizio di notifica push.

Ad esempio, durante il giorno di contrattazione di un mercato azionario, puoi impostare la scadenza di un aggiornamento del prezzo del titolo al doppio dell'intervallo di invio (ad esempio un'ora dopo la ricezione se invii le notifiche ogni mezz'ora). Per fare un altro esempio, un'applicazione di notizie potrebbe stabilire che un giorno è un tempo di scadenza appropriato per un aggiornamento giornaliero delle notizie.

Notifiche push e risparmio di batteria

Battery saver prolunga la durata della batteria limitando le attività in background sul dispositivo. Windows 10 consente all'utente di impostare il risparmio batteria in modo che si attivi automaticamente quando la batteria scende al di sotto di una determinata soglia. Quando il risparmio della batteria è attivo, la ricezione delle notifiche push viene disabilitata per risparmiare energia. Ma ci sono un paio di eccezioni. Le seguenti impostazioni per il risparmio della batteria di Windows 10 (che si trovano nell'app Settings ) consentono alla tua app di ricevere notifiche push anche quando il risparmio della batteria è attivo.

  • Consenti le notifiche push da qualsiasi app mentre sei in risparmio batteria: Questa impostazione consente a tutte le app di ricevere le notifiche push mentre il risparmio batteria è attivo. Nota che questa impostazione si applica solo a Windows 10 per le edizioni desktop (Home, Pro, Enterprise e Education).
  • Sempre consentito: Questa impostazione consente a specifiche app di funzionare in background mentre il risparmio batteria è attivo, compresa la ricezione di notifiche push. Questo elenco viene gestito manualmente dall'utente.

Non c'è modo di verificare lo stato di queste due impostazioni, ma puoi controllare lo stato del risparmio della batteria. In Windows 10, utilizza la proprietà EnergySaverStatus per verificare lo stato di risparmio della batteria. La tua applicazione può anche utilizzare l'evento EnergySaverStatusChanged per ascoltare le modifiche al risparmio della batteria.

Se la tua applicazione dipende molto dalle notifiche push, ti consigliamo di avvisare gli utenti che non potranno ricevere notifiche quando il risparmio batteria è attivo e di facilitare la regolazione delle impostazioni del risparmio batteria . Utilizzando lo schema URI delle impostazioni del risparmio batteria in Windows 10, ms-settings:batterysaver-settings, puoi fornire un comodo link all'app Impostazioni.

Suggerimento

Quando si avvisano gli utenti delle impostazioni di risparmio della batteria, si consiglia di fornire un modo per sopprimere il messaggio in futuro. Ad esempio, la casella di controllo dontAskMeAgainBox nel seguente esempio persiste la preferenza dell'utente in LocalSettings.

Ecco un esempio di come verificare se il risparmio batteria è attivo in Windows 10. Questo esempio notifica l'utente e lancia l'applicazione Impostazioni per le impostazioni del risparmio batteria. Il sito dontAskAgainSetting permette all'utente di sopprimere il messaggio se non vuole essere avvisato di nuovo.

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.System;
using Windows.System.Power;
...
...
async public void CheckForEnergySaving()
{
   //Get reminder preference from LocalSettings
   bool dontAskAgain;
   var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
   object dontAskSetting = localSettings.Values["dontAskAgainSetting"];
   if (dontAskSetting == null)
   {  // Setting does not exist
      dontAskAgain = false;
   }
   else
   {  // Retrieve setting value
      dontAskAgain = Convert.ToBoolean(dontAskSetting);
   }
   
   // Check if battery saver is on and that it's okay to raise dialog
   if ((PowerManager.EnergySaverStatus == EnergySaverStatus.On)
         && (dontAskAgain == false))
   {
      // Check dialog results
      ContentDialogResult dialogResult = await saveEnergyDialog.ShowAsync();
      if (dialogResult == ContentDialogResult.Primary)
      {
         // Launch battery saver settings (settings are available only when a battery is present)
         await Launcher.LaunchUriAsync(new Uri("ms-settings:batterysaver-settings"));
      }

      // Save reminder preference
      if (dontAskAgainBox.IsChecked == true)
      {  // Don't raise dialog again
         localSettings.Values["dontAskAgainSetting"] = "true";
      }
   }
}
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.System.h>
#include <winrt/Windows.System.Power.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Navigation.h>
using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Storage;
using namespace winrt::Windows::System;
using namespace winrt::Windows::System::Power;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Navigation;
...
winrt::fire_and_forget CheckForEnergySaving()
{
    // Get reminder preference from LocalSettings.
    bool dontAskAgain{ false };
    auto localSettings = ApplicationData::Current().LocalSettings();
    IInspectable dontAskSetting = localSettings.Values().Lookup(L"dontAskAgainSetting");
    if (!dontAskSetting)
    {
        // Setting doesn't exist.
        dontAskAgain = false;
    }
    else
    {
        // Retrieve setting value
        dontAskAgain = winrt::unbox_value<bool>(dontAskSetting);
    }

    // Check whether battery saver is on, and whether it's okay to raise dialog.
    if ((PowerManager::EnergySaverStatus() == EnergySaverStatus::On) && (!dontAskAgain))
    {
        // Check dialog results.
        ContentDialogResult dialogResult = co_await saveEnergyDialog().ShowAsync();
        if (dialogResult == ContentDialogResult::Primary)
        {
            // Launch battery saver settings
            // (settings are available only when a battery is present).
            co_await Launcher::LaunchUriAsync(Uri(L"ms-settings:batterysaver-settings"));
        }

        // Save reminder preference.
        if (dontAskAgainBox().IsChecked())
        {
            // Don't raise the dialog again.
            localSettings.Values().Insert(L"dontAskAgainSetting", winrt::box_value(true));
        }
    }
}

Questo è lo XAML per la ContentDialog presente in questo esempio.

<ContentDialog x:Name="saveEnergyDialog"
               PrimaryButtonText="Open battery saver settings"
               SecondaryButtonText="Ignore"
               Title="Battery saver is on."> 
   <StackPanel>
      <TextBlock TextWrapping="WrapWholeWords">
         <LineBreak/><Run>Battery saver is on and you may 
          not receive push notifications.</Run><LineBreak/>
         <LineBreak/><Run>You can choose to allow this app to work normally
         while in battery saver, including receiving push notifications.</Run>
         <LineBreak/>
      </TextBlock>
      <CheckBox x:Name="dontAskAgainBox" Content="OK, got it."/>
   </StackPanel>
</ContentDialog>