Partilhar via


Visão geral dos Serviços de Notificação por Push do Windows (WNS)

Os Serviços de Notificação por Push do Windows (WNS) permitem que desenvolvedores de terceiros enviem notificações de aviso, bloco, ícone e atualizações raw a partir do seu próprio serviço de nuvem. Isso fornece um mecanismo para fornecer novas atualizações aos seus usuários de forma eficiente em termos de energia e confiável.

Como funciona

O diagrama a seguir mostra o fluxo de dados completo para o envio de uma notificação por push. Envolve as seguintes etapas:

  1. Seu aplicativo solicita um canal de notificação por push do WNS.
  2. O Windows pede ao WNS para criar um canal de notificação. Esse canal é retornado ao dispositivo chamador na forma de um URI (Uniform Resource Identifier).
  3. O URI do canal de notificação é retornado pelo WNS ao seu aplicativo.
  4. Seu aplicativo envia o URI para seu próprio serviço de nuvem. Em seguida, você armazena o URI em seu próprio serviço de nuvem para que possa acessar o URI ao enviar notificações. O URI é uma interface entre seu próprio aplicativo e seu próprio serviço; É da sua responsabilidade implementar esta interface com padrões Web seguros e protegidos.
  5. Quando seu serviço de nuvem tem uma atualização para enviar, ele notifica o WNS usando o URI do canal. Isso é feito emitindo uma solicitação HTTP POST, incluindo o payload de notificação, através de Secure Sockets Layer (SSL). Esta etapa requer autenticação.
  6. O WNS recebe a solicitação e encaminha a notificação para o dispositivo apropriado.

diagrama de fluxo de dados para notificação por push do WNS

Registar a sua aplicação e receber as credenciais para o seu serviço na nuvem

Antes de enviar notificações usando o WNS, seu aplicativo deve ser registrado no Painel da Loja, conforme descrito aqui.

Solicitar um canal de notificação

Quando uma app capaz de receber notificações por push é executada, deve primeiro solicitar um canal de notificação através do CreatePushNotificationChannelForApplicationAsync. Para obter uma discussão completa e um código de exemplo, consulte Como solicitar, criar e salvar um canal de notificação. Esta API retorna um URI de canal que está exclusivamente ligado à aplicação que realiza a chamada e ao seu tile, através do qual todos os tipos de notificação podem ser enviados.

Depois que o aplicativo cria com êxito um URI de canal, ele o envia para seu serviço de nuvem, juntamente com quaisquer metadados específicos do aplicativo que devem ser associados a esse URI.

Observações importantes

  • Não garantimos que o URI do canal de notificação de um aplicativo permanecerá sempre o mesmo. Aconselhamos que o aplicativo solicite um novo canal toda vez que for executado e atualize seu serviço quando o URI for alterado. O desenvolvedor nunca deve modificar o URI do canal e deve considerá-lo como uma cadeia de caracteres de caixa preta. Neste momento, os URIs do canal expiram após 30 dias. Se o seu aplicativo do Windows 10 renovar periodicamente seu canal em segundo plano, você poderá baixar o de exemplo de notificações por push e periódicas do para Windows 8.1 e reutilizar seu código-fonte e/ou o padrão demonstrado.
  • A interface entre o serviço de nuvem e o aplicativo cliente é implementada por você, o desenvolvedor. Recomendamos que o aplicativo passe por um processo de autenticação com seu próprio serviço e transmita dados por meio de um protocolo seguro, como HTTPS.
  • É importante que o serviço de nuvem sempre garanta que o URI do canal use o domínio "notify.windows.com". O serviço nunca deve enviar notificações por push para um canal em qualquer outro domínio. Se o retorno de chamada do seu aplicativo for comprometido, um invasor mal-intencionado poderá enviar um URI de canal para falsificar o WNS. Sem inspecionar o domínio, seu serviço de nuvem pode potencialmente divulgar informações a esse invasor sem saber. O subdomínio do URI do canal está sujeito a alterações e não deve ser considerado ao validar o URI do canal.
  • Se o seu serviço de nuvem tentar enviar uma notificação para um canal expirado, o WNS retornará o código de resposta 410. Em resposta a esse código, seu serviço não deve mais tentar enviar notificações para esse URI.

Autenticando seu serviço de nuvem

Para enviar uma notificação, o serviço de nuvem deve ser autenticado por meio do WNS. A primeira etapa desse processo ocorre quando você registra seu aplicativo no Painel da Microsoft Store. Durante o processo de registro, seu aplicativo recebe um identificador de segurança de pacote (SID) e uma chave secreta. Essas informações são usadas pelo seu serviço de nuvem para autenticar com o WNS.

O esquema de autenticação do WNS é implementado usando o perfil de credenciais do cliente do protocolo OAuth 2.0 . O serviço de nuvem é autenticado com o WNS fornecendo suas credenciais (SID do pacote e chave secreta). Em troca, recebe um token de acesso. Esse token de acesso permite que um serviço de nuvem envie uma notificação. O token é necessário com cada solicitação de notificação enviada ao WNS.

A um nível elevado, a cadeia de informação é a seguinte:

  1. O serviço de nuvem envia suas credenciais para o WNS por HTTPS seguindo o protocolo OAuth 2.0. Isso autentica o serviço com o WNS.
  2. O WNS retorna um token de acesso se a autenticação tiver sido bem-sucedida. Esse token de acesso é usado em todas as solicitações de notificação subsequentes até expirar.

Diagrama do WNS para autenticação do serviço de nuvem

Na autenticação com WNS, o serviço de nuvem envia uma solicitação HTTP sobre SSL (Secure Sockets Layer). Os parâmetros são fornecidos no formato "application/x-www-for-urlencoded". Forneça o SID do pacote no campo "client_id" e sua chave secreta no campo "client_secret", conforme mostrado no exemplo a seguir. Para obter detalhes de sintaxe, consulte a referência à solicitação de token de acesso .

Note

Este é apenas um exemplo, não cortar e colar código que você pode usar com sucesso em seu próprio código. 

 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

O WNS autentica o serviço de nuvem e, se bem-sucedido, envia uma resposta de "200 OK". O token de acesso é retornado nos parâmetros incluídos no corpo da resposta HTTP, usando o tipo de mídia "application/json". Depois que o serviço receber o token de acesso, você estará pronto para enviar notificações.

O exemplo a seguir mostra uma resposta de autenticação bem-sucedida, incluindo o token de acesso. Para obter detalhes de sintaxe, consulte os cabeçalhos de solicitação e resposta do serviço de notificação por 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"
 }

Observações importantes

  • O protocolo OAuth 2.0 suportado neste procedimento segue a versão preliminar V16.
  • O OAuth Request for Comments (RFC) usa o termo "cliente" para se referir ao serviço de nuvem.
  • Pode haver alterações nesse procedimento quando o rascunho do OAuth for finalizado.
  • O token de acesso pode ser reutilizado para várias solicitações de notificação. Isso permite que o serviço de nuvem se autentique apenas uma vez para enviar muitas notificações. No entanto, quando o token de acesso expira, o serviço de nuvem deve se autenticar novamente para receber um novo token de acesso.

Enviar uma notificação

Usando o URI do canal, o serviço de nuvem pode enviar uma notificação sempre que tiver uma atualização para o usuário.

O token de acesso descrito acima pode ser reutilizado para várias solicitações de notificação; O Cloud Server não é obrigado a solicitar um novo token de acesso para cada notificação. Se o token de acesso tiver expirado, a solicitação de notificação retornará um erro. Recomendamos que você não tente reenviar sua notificação mais de uma vez se o token de acesso for rejeitado. Se encontrar este erro, terá de solicitar um novo token de acesso e reenviar a notificação. Para obter o código de erro exato, consulte Códigos de resposta de notificação por push.

  1. O serviço de nuvem faz um HTTP POST para o URI do canal. Esta solicitação deve ser feita por SSL e contém os cabeçalhos necessários e a carga útil da notificação. O cabeçalho de autorização deve incluir o token de acesso adquirido para autorização.

    Um exemplo de solicitação é mostrado aqui. Para obter detalhes de sintaxe, consulte Códigos de resposta de notificação por push.

    Para obter detalhes sobre como compor a carga útil de notificação, consulte Guia de início rápido : enviando uma notificação por push. A carga útil de uma notificação por push de um bloco, notificação de alerta ou notificação de emblema é fornecida como conteúdo XML que adere ao respetivo schema de blocos adaptativo definido ou schema de blocos legado. A carga útil de uma notificação bruta não tem uma estrutura especificada. É estritamente definido pelo aplicativo.

     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. O WNS responde para indicar que a notificação foi recebida e será entregue na próxima oportunidade disponível. No entanto, o WNS não fornece confirmação de ponta a ponta de que sua notificação foi recebida pelo dispositivo ou aplicativo.

Este diagrama ilustra o fluxo de dados:

diagrama WNS para enviar uma notificação

Observações importantes

  • O WNS não garante a confiabilidade ou latência de uma notificação.
  • As notificações nunca devem incluir dados confidenciais, sensíveis ou pessoais.
  • Para enviar uma notificação, o serviço de nuvem deve primeiro autenticar-se com o WNS e receber um token de acesso.
  • Um token de acesso só permite que um serviço de nuvem envie notificações para o único aplicativo para o qual o token foi criado. Um token de acesso não pode ser usado para enviar notificações em vários aplicativos. Portanto, se o seu serviço de nuvem oferecer suporte a vários aplicativos, ele deverá fornecer o token de acesso correto para o aplicativo ao enviar uma notificação para cada URI de canal.
  • Quando o dispositivo estiver offline, normalmente, o WNS armazenará um de cada tipo de notificação (azulejo, selo, notificação de alerta) para cada URI de canal e nenhuma notificação em bruto.
  • Em cenários em que o conteúdo da notificação é personalizado para o usuário, o WNS recomenda que o serviço de nuvem envie imediatamente essas atualizações quando elas forem recebidas. Exemplos desse cenário incluem atualizações de feed de mídia social, convites de comunicação instantânea, notificações de novas mensagens ou alertas. Como alternativa, você pode ter cenários em que a mesma atualização genérica é frequentemente entregue a um grande subconjunto de seus usuários; por exemplo, atualizações meteorológicas, de ações e de notícias. As diretrizes do WNS especificam que a frequência dessas atualizações deve ser, no máximo, uma a cada 30 minutos. O usuário final ou o WNS podem determinar que atualizações de rotina mais frequentes sejam abusivas.
  • A Plataforma de Notificação do Windows mantém uma conexão de dados periódica com o WNS para manter o soquete ativo e íntegro. Se não houver aplicativos solicitando ou usando canais de notificação, o soquete não será criado.

Expiração de notificações de mosaico e emblema

Por padrão, as notificações de azulejo e badges expiram três dias após serem descarregadas. Quando uma notificação expira, o conteúdo é removido do bloco ou da fila e não é mais mostrado ao usuário. É uma prática recomendada definir uma expiração (usando um tempo que faça sentido para seu aplicativo) em todas as notificações de bloco e selo para que o conteúdo do bloco não persista por mais tempo do que é relevante. Um tempo de expiração explícito é essencial para um conteúdo com uma vida útil definida. Isso também garante a remoção de conteúdo obsoleto se o serviço de nuvem parar de enviar notificações ou se o usuário se desconectar da rede por um longo período.

Seu serviço de nuvem pode definir uma expiração para cada notificação definindo o cabeçalho X-WNS-TTL HTTP para especificar o tempo (em segundos) em que sua notificação permanecerá válida depois de enviada. Para obter mais informações, consulte os cabeçalhos de solicitação e resposta do serviço de notificação por push .

Por exemplo, durante o dia de negociação ativo de um mercado de ações, você pode definir a expiração de uma atualização do preço de uma ação para o dobro do seu intervalo de envio (como uma hora após o recebimento se você estiver enviando notificações a cada meia hora). Como outro exemplo, um aplicativo de notícias pode determinar que um dia é um tempo de expiração apropriado para uma atualização diária do bloco de notícias.

Notificações push e economia de bateria

A poupança de bateria prolonga a vida útil da bateria limitando a atividade em segundo plano no dispositivo. O Windows 10 permite que o usuário defina a economia de bateria para ligar automaticamente quando a bateria cair abaixo de um limite especificado. Quando a poupança de bateria está ativada, a receção de notificações push é desativada para poupar energia. Mas há algumas exceções a isso. As seguintes configurações de economia de bateria do Windows 10 (encontradas em Configurações do Windows) permitem que seu aplicativo receba notificações por push mesmo quando a economia de bateria está ativada.

  • Permitir notificações push de qualquer aplicação enquanto estiver a poupar bateria: esta definição permite que todas as aplicações recebam notificações push enquanto a poupança de bateria está ativada. Tenha em atenção que esta definição se aplica apenas ao Windows 10 para edições de ambiente de trabalho (Home, Pro, Enterprise e Education).
  • Sempre permitido: esta definição permite que aplicações específicas sejam executadas em segundo plano enquanto a poupança de bateria está ativada, incluindo a receção de notificações push. Esta lista é mantida manualmente pelo utilizador.

Não há como verificar o estado dessas duas configurações, mas você pode verificar o estado da economia de bateria. No Windows 10, use a propriedade EnergySaverStatus para verificar o estado de economia de bateria. O seu aplicativo também pode usar o evento EnergySaverStatusChanged para monitorizar alterações na poupança de bateria.

Se o seu aplicativo depende muito de notificações push, recomendamos notificar os usuários de que eles podem não receber notificações enquanto a economia de bateria estiver ativada e facilitar o ajuste das configurações de economia de bateria. Usando o esquema de URI de configurações de economia de bateria no Windows, ms-settings:batterysaver-settingsvocê pode fornecer um link conveniente para as Configurações do Windows.

Tip

Ao notificar o usuário sobre as configurações de economia de bateria, recomendamos fornecer uma maneira de suprimir a mensagem no futuro. Por exemplo, a dontAskMeAgainBox caixa de seleção no exemplo a seguir persiste a preferência do usuário em LocalSettings.

Eis um exemplo de como verificar se a poupança de bateria está ativada no Windows 10. Este exemplo notifica o usuário e inicia Configurações para configurações de economia de bateria. O dontAskAgainSetting permite que o usuário suprima a mensagem se não quiser ser notificado novamente.

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

Este é o XAML para o ContentDialog apresentado neste exemplo.

<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>