Idioma: HTML | XAML

Início rápido: enviando uma notificação por push (XAML)

Observação  Essa funcionalidade geralmente não é implementada usando JavaScript. Em vez disso, use o procedimento fornecido aqui.

O servidor na nuvem pode enviar uma notificação por push ao aplicativo por meio dos Serviços de Notificação por Push do Windows (WNS). Este procedimento se aplica a notificações de bloco, do sistema e brutas por push.

Objetivo: Para criar e enviar uma notificação de bloco, do sistema ou bruta por push.

Pré-requisitos

Para compreender este tópico ou para usar o código que ele oferece, você precisará de:

Instruções

1. Incluir as referências de namespace necessárias

Os exemplos fornecidos neste tópicos podem ser usados no estado atual, mas exigem que o código inclua estas referências de namespace:



using System.Net;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Web;
using System.Text;

2. Crie uma solicitação HTTP POST.

O parâmetro uri é o URI (Uniform Resource Identifier) solicitado pelo aplicativo e passado para o servidor na nuvem. Para saber mais, veja Como solicitar, criar e salvar um canal de notificação.



HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.Method = "POST";

3. Adicione os cabeçalhos requeridos.

Há quatro cabeçalhos que devem ser incluídos em todas as notificações por push: X-WNS-Type, Content-Type, Content-Length e Authorization.

  • O cabeçalho X-WNS-Type especifica se é uma notificação de bloco, do sistema ou bruta.
  • O cabeçalho Content-Type é definido dependendo do valor de X-WNS-Type.
  • O cabeçalho Content-Length fornece o tamanho da carga de notificação incluída.
  • O cabeçalho Authorization especifica a credencial de autenticação que permite a você enviar uma notificação por push para este usuário por este canal.

O parâmetro accessToken do cabeçalho Authorization especifica o token de acesso, armazenado no servidor, que foi recebido dos WNS quando o servidor na nuvem foi autenticado. Sem o token de acesso, sua notificação será rejeitada.

Para obter uma lista completa de cabeçalhos possíveis, consulte Cabeçalhos de solicitação e resposta de serviço de notificação por push.



request.Headers.Add("X-WNS-Type", notificationType);
request.ContentType = contentType;
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));

4. Adicione o conteúdo preparado.

Em relação à solicitação HTTP, o conteúdo XML da notificação é um blob de dados no corpo da solicitação. Por exemplo, nenhuma verificação é feita para saber se o XML corresponde à especificação X-WNS-Type. O conteúdo é especificado como uma carga XML e, aqui, é adicionado à solicitação como um fluxo de bytes.



byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
                        
using (Stream requestStream = request.GetRequestStream())
    requestStream.Write(contentInBytes, 0, contentInBytes.Length);

5. Ouça uma resposta do WNS que reconheça o recebimento da notificação

Observação  Você nunca receberá uma confirmação de entrega de uma notificação, apenas um reconhecimento de que ela foi recebida pelo WNS.


using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
    return webResponse.StatusCode.ToString();

6. Manipular códigos de resposta do WNS

Há vários códigos de resposta que o seu serviço de aplicativo pode receber ao enviar uma notificação. Alguns desses códigos de resposta são mais comuns que outros e podem ser tratados facilmente dentro de um bloco catch.



catch (WebException webException)
{
    HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;

HttpStatusCode.Unauthorized: O token de acesso apresentado expirou. Obtenha um novo e tente enviar sua notificação outra vez. Como o token de acesso em cache expira após 24 horas, você pode esperar obter essa resposta do WNS pelo menos uma vez ao dia. Recomendamos que você implemente uma política de máximo de novas tentativas.



    if (status == HttpStatusCode.Unauthorized)
    {
        GetAccessToken(secret, sid);
        return PostToWns(uri, xml, secret, sid, notificationType, contentType);
    }

HttpStatusCode.Gone / HttpStatusCode.NotFound: O URI do canal não é mais válido. Remova esse canal do seu banco de dados para evitar novas tentativas de enviar notificações para ele. Na próxima vez em que esse usuário iniciar seu aplicativo, solicite um novo canal do WNS. Seu aplicativo deve detectar que seu canal foi alterado, o que deve fazer com que o aplicativo envie o novo URI do canal ao seu servidor de aplicativos. Para saber mais, veja Como solicitar, criar e salvar um canal de notificação.



    else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound)
    {
        return "";
    }

HttpStatusCode.NotAcceptable: esse canal está sendo limitado por WNS. Implemente uma estratégia de nova tentativa que reduza exponencialmente a quantidade de notificações enviadas, a fim de evitar uma nova limitação. Além disso, repense cenários que estejam fazendo com que suas notificações sejam limitadas. Você fornecerá uma experiência mais rica ao usuário, limitando as notificações enviadas àqueles que adicionarem valor verdadeiro.



    else if (status == HttpStatusCode.NotAcceptable)
    {
        return "";
    }

Outros códigos de resposta: WNS respondeu com um código de resposta menos comum. Registre esse código para auxiliar na depuração. Veja Solicitação de serviço de notificação por push e cabeçalhos de resposta para obter uma lista completa de códigos de resposta do WNS.



    else
    {
        string[] debugOutput = {
                                   status.ToString(),
                                   webException.Response.Headers["X-WNS-Debug-Trace"],
                                   webException.Response.Headers["X-WNS-Error-Description"],
                                   webException.Response.Headers["X-WNS-Msg-ID"],
                                   webException.Response.Headers["X-WNS-Status"]
                               };
        return string.Join(" | ", debugOutput);            
    }

7. Encapsule o código em uma única função

O exemplo a seguir empacota o código dado nas etapas anteriores em uma única função. A função compõe a solicitação HTTP POST que contém uma notificação a ser enviada ao WNS. Alterando o valor do parâmetro type e ajustando os cabeçalhos adicionais, esse código pode ser usado para notificações por push do sistema, de bloco ou brutas. Você pode usar essa função como parte do seu código de servidor na nuvem.

Observe que a manipulação de erros dessa função inclui a possibilidade do token de acesso ter expirado. Neste caso, ela chama outra função do servidor na nuvem que realiza uma nova autenticação com o WNS para obter o novo token de acesso. Em seguida, ela faz uma nova chamada à função original.



// Post to WNS
public string PostToWns(string secret, string sid, string uri, string xml, string notificationType, string contentType)
{
    try
    {
        // You should cache this access token.
        var accessToken = GetAccessToken(secret, sid);

        byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);

        HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
        request.Method = "POST";
        request.Headers.Add("X-WNS-Type", notificationType);
        request.ContentType = contentType;
        request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken.AccessToken));

        using (Stream requestStream = request.GetRequestStream())
            requestStream.Write(contentInBytes, 0, contentInBytes.Length);

        using (HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse())
            return webResponse.StatusCode.ToString();
    }
    
    catch (WebException webException)
    {
        HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;

        if (status == HttpStatusCode.Unauthorized)
        {
            // The access token you presented has expired. Get a new one and then try sending
            // your notification again.
              
            // Because your cached access token expires after 24 hours, you can expect to get 
            // this response from WNS at least once a day.

            GetAccessToken(secret, sid);

            // We recommend that you implement a maximum retry policy.
            return PostToWns(uri, xml, secret, sid, notificationType, contentType);
        }
        else if (status == HttpStatusCode.Gone || status == HttpStatusCode.NotFound)
        {
            // The channel URI is no longer valid.

            // Remove this channel from your database to prevent further attempts
            // to send notifications to it.

            // The next time that this user launches your app, request a new WNS channel.
            // Your app should detect that its channel has changed, which should trigger
            // the app to send the new channel URI to your app server.

            return "";
        }
        else if (status == HttpStatusCode.NotAcceptable)
        {
            // This channel is being throttled by WNS.

            // Implement a retry strategy that exponentially reduces the amount of
            // notifications being sent in order to prevent being throttled again.

            // Also, consider the scenarios that are causing your notifications to be throttled. 
            // You will provide a richer user experience by limiting the notifications you send 
            // to those that add true value.

            return "";
        }
        else
        {
            // WNS responded with a less common error. Log this error to assist in debugging.

            // You can see a full list of WNS response codes here:
            // http://msdn.microsoft.com/en-us/library/windows/apps/hh868245.aspx#wnsresponsecodes

            string[] debugOutput = {
                                       status.ToString(),
                                       webException.Response.Headers["X-WNS-Debug-Trace"],
                                       webException.Response.Headers["X-WNS-Error-Description"],
                                       webException.Response.Headers["X-WNS-Msg-ID"],
                                       webException.Response.Headers["X-WNS-Status"]
                                   };
            return string.Join(" | ", debugOutput);            
        }
    }

    catch (Exception ex)
    {
        return "EXCEPTION: " + ex.Message;
    }
}

// Authorization
[DataContract]
public class OAuthToken
{
    [DataMember(Name = "access_token")]
    public string AccessToken { get; set; }
    [DataMember(Name = "token_type")]
    public string TokenType { get; set; }
}

private OAuthToken GetOAuthTokenFromJson(string jsonString)
{
    using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
    {
        var ser = new DataContractJsonSerializer(typeof(OAuthToken));
        var oAuthToken = (OAuthToken)ser.ReadObject(ms);
        return oAuthToken;
    }
}

protected OAuthToken GetAccessToken(string secret, string sid)
{
    var urlEncodedSecret = HttpUtility.UrlEncode(secret);
    var urlEncodedSid = HttpUtility.UrlEncode(sid);

    var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", 
                             urlEncodedSid, 
                             urlEncodedSecret);

    string response;
    using (var client = new WebClient())
    {
        client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
        response = client.UploadString("https://login.live.com/accesstoken.srf", body);
    }
    return GetOAuthTokenFromJson(response);
}

A seguir, um conteúdo de exemplo para uma solicitação HTTP POST para uma notificação por push do sistema.



POST https://db3.notify.windows.com/?token=AgUAAADCQmTg7OMlCg%2fK0K8rBPcBqHuy%2b1rTSNPMuIzF6BtvpRdT7DM4j%2fs%2bNNm8z5l1QKZMtyjByKW5uXqb9V7hIAeA3i8FoKR%2f49ZnGgyUkAhzix%2fuSuasL3jalk7562F4Bpw%3d HTTP/1.1
Authorization: Bearer EgAaAQMAAAAEgAAACoAAPzCGedIbQb9vRfPF2Lxy3K//QZB79mLTgK
X-WNS-RequestForStatus: true
X-WNS-Type: wns/toast
Content-Type: text/xml
Host: db3.notify.windows.com
Content-Length: 196

<toast launch="">
  <visual lang="en-US">
    <binding template="ToastImageAndText01">
      <image id="1" src="World" />
      <text id="1">Hello</text>
    </binding>
  </visual>
</toast>

A seguir, um exemplo de resposta HTTP enviado para o servidor na nuvem por WNS em resposta à solicitação HTTP POST.



HTTP/1.1 200 OK
Content-Length: 0
X-WNS-DEVICECONNECTIONSTATUS: connected
X-WNS-STATUS: received
X-WNS-MSG-ID: 3CE38FF109E03A74
X-WNS-DEBUG-TRACE: DB3WNS4011534

Resumo

Neste Guia de início rápido, você compôs uma solicitação HTTP POST a ser enviada ao WNS. O WNS, por sua vez, fornece a notificação ao seu aplicativo. Neste ponto, você já registrou o seu aplicativo, autenticou o servidor na nuvem com WNS, criou conteúdo XML para definir a sua notificação e enviou essa notificação do seu servidor para o seu aplicativo.

Tópicos relacionados

Como solicitar, criar e salvar um canal de notificação
Cabeçalhos de solicitação e resposta de serviço de notificação por push
Visão geral dos Serviços de Notificação por Push do Windows (WNS)
Introdução aos Serviços Móveis
Exemplo de notificações por push e periódicas

 

 

Mostrar:
© 2015 Microsoft