Share via


Schnellstart: Senden einer Pushbenachrichtigung (XAML)

Ihr Cloudserver kann über die Windows-Pushbenachrichtigungsdienste (WNS) eine Pushbenachrichtigung an Ihre App senden. Dieses Verfahren gilt für Kachel-, Popup-, Signal- und Unformatierte Pushbenachrichtigungen.

Ziel: So erstellen und senden Sie eine Kachel-, Popup-, Signal- oder unformatierte Pushbenachrichtigung.

Voraussetzungen

Um dieses Thema zu verstehen oder den bereitgestellten Code zu verwenden, benötigen Sie Folgendes:

Anweisungen

1. Einschließen der erforderlichen Namespaceverweise

Die in diesem Thema aufgeführten Beispiele können unverändert verwendet werden, erfordern jedoch, dass Ihr Code die folgenden Namespaceverweise enthält:

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

2. Erstellen einer HTTP POST-Anforderung

Der uri Parameter ist der URI (Uniform Resource Identifier), der von der App angefordert und an den Cloudserver übergeben wird. Weitere Informationen finden Sie unter Anfordern, Erstellen und Speichern eines Benachrichtigungskanals.

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

3. Hinzufügen der erforderlichen Header

Es gibt vier erforderliche Header, die in allen Pushbenachrichtigungen enthalten sein müssen: X-WNS-Type, Content-Type, Content-Length und Authorization.

  • Der X-WNS-Type-Header gibt an, ob es sich um eine Kachel-, Popup-, Signal- oder unformatierte Benachrichtigung handelt.
  • Der Inhaltstyp wird abhängig vom Wert des X-WNS-Type festgelegt.
  • Die Inhaltslänge gibt die Größe der enthaltenen Benachrichtigungsnutzlast an.
  • Der Autorisierungsheader gibt die Anmeldeinformationen für die Authentifizierung an, mit denen Sie über diesen Kanal eine Pushbenachrichtigung an diesen Benutzer senden können.

Der accessToken-Parameter des Autorisierungsheaders gibt das auf dem Server gespeicherte Zugriffstoken an, das von WNS empfangen wurde, als der Cloudserver die Authentifizierung angefordert hat. Ohne das Zugriffstoken wird Ihre Benachrichtigung abgelehnt.

Eine vollständige Liste der möglichen Header finden Sie unter Anforderungs- und Antwortheader des Pushbenachrichtigungsdiensts.

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

4. Hinzufügen der vorbereiteten Inhalte

Was die HTTP-Anforderung angeht, ist der XML-Inhalt der Benachrichtigung ein Datenblob im Anforderungstext. Für instance wird nicht überprüft, ob der XML-Code der X-WNS-Type-Spezifikation entspricht. Der Inhalt wird als XML-Nutzlast angegeben und hier der Anforderung als Bytestrom hinzugefügt.

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

5. Lauschen Auf eine Antwort von WNS, die den Empfang der Benachrichtigung bestätigt

Hinweis

Sie erhalten nie eine Lieferbestätigung für eine Benachrichtigung, nur eine Bestätigung, dass sie von WNS empfangen wurde.

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

6. Behandeln von WNS-Antwortcodes

Es gibt viele Antwortcodes, die Ihr App-Dienst empfangen kann, wenn er eine Benachrichtigung sendet. Einige dieser Antwortcodes sind häufiger als andere und können problemlos in einem Catch-Block behandelt werden.

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

HttpStatusCode.Unauthorized: Das angezeigte Zugriffstoken ist abgelaufen. Rufen Sie eine neue ab, und versuchen Sie dann erneut, Ihre Benachrichtigung zu senden. Da Ihr zwischengespeichertes Zugriffstoken nach 24 Stunden abläuft, können Sie davon ausgehen, dass Sie diese Antwort mindestens einmal täglich von WNS erhalten. Es wird empfohlen, eine Richtlinie für maximale Wiederholungsversuche zu implementieren.

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

HttpStatusCode.Gone / HttpStatusCode.NotFound: Der Kanal-URI ist nicht mehr gültig. Entfernen Sie diesen Kanal aus Ihrer Datenbank, um weitere Versuche zu verhindern, Benachrichtigungen an ihn zu senden. Wenn dieser Benutzer Ihre App das nächste Mal startet, fordern Sie einen neuen WNS-Kanal an. Ihre App sollte erkennen, dass sich ihr Kanal geändert hat, was die App auslösen sollte, um den neuen Kanal-URI an Ihren App-Server zu senden. Weitere Informationen finden Sie unter Anfordern, Erstellen und Speichern eines Benachrichtigungskanals.

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

HttpStatusCode.NotAcceptable: Dieser Kanal wird von WNS gedrosselt. Implementieren Sie eine Wiederholungsstrategie, die die Anzahl der gesendeten Benachrichtigungen exponentiell reduziert, um eine erneute Drosselung zu verhindern. Überdenken Sie außerdem Szenarien, die dazu führen, dass Ihre Notifikalität gedrosselt wird. Sie bieten eine umfassendere Benutzererfahrung, indem Sie die gesendeten Benachrichtigungen auf diejenigen beschränken, die einen echten Wert hinzufügen.

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

Andere Antwortcodes: WNS reagierte mit einem weniger häufigen Antwortcode. Protokollieren Sie diesen Code, um das Debuggen zu unterstützen. Eine vollständige Liste der WNS-Antwortcodes finden Sie unter Anforderungs- und Antwortheader des Pushbenachrichtigungsdiensts .

    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. Kapseln Sie den Code in eine einzelne Funktion

Im folgenden Beispiel wird der in den vorherigen Schritten angegebene Code in eine einzelne Funktion verpackt. Diese Funktion stellt die HTTP POST-Anforderung zusammen, die eine Benachrichtigung enthält, die an WNS gesendet werden soll. Durch Ändern des Werts des Typparameters und Anpassen zusätzlicher Header kann dieser Code für Popup-, Kachel-, Badge- oder unformatierte Pushbenachrichtigungen verwendet werden. Sie können diese Funktion als Teil Ihres Cloudservercodes verwenden.

Beachten Sie, dass die Fehlerbehandlung in dieser Funktion die Situation umfasst, in der das Zugriffstoken abgelaufen ist. In diesem Fall wird eine andere Cloudserverfunktion aufgerufen, die sich erneut bei WNS authentifiziert, um ein neues Zugriffstoken zu erhalten. Anschließend erfolgt ein neuer Aufruf der ursprünglichen Funktion.

// 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:
            // https://msdn.microsoft.com/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);
}

Im Folgenden werden Beispielinhalte für eine HTTP POST-Anforderung für eine Popuppushbenachrichtigung gezeigt.

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>

Im Folgenden sehen Sie eine BEISPIEL-HTTP-Antwort, die von WNS als Antwort auf die HTTP POST-Anforderung an den Cloudserver gesendet wurde.

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

Zusammenfassung

In dieser Schnellstartanleitung haben Sie eine HTTP POST-Anforderung erstellt, die an WNS gesendet werden soll. WNS wiederum übermittelt die Benachrichtigung an Ihre App. Zu diesem Zeitpunkt haben Sie Ihre App registriert, Ihren Cloudserver bei WNS authentifiziert, XML-Inhalte erstellt, um Ihre Benachrichtigung zu definieren, und diese Benachrichtigung von Ihrem Server an Ihre App gesendet.