Registrieren von Ihrem App-Back-End

Wie in den vorherigen Abschnitten erwähnt, müssen Geräte eine oder mehrere Registrierungen in einem Benachrichtigungshub erstellen, um Pushbenachrichtigungen zu erhalten. Eine Möglichkeit, diese Registrierung abzuschließen, besteht darin, dass die mobilen Geräte direkt den Benachrichtigungshub kontaktieren, um ihren PNS-Handle und ihre Tags anzugeben (oder zu aktualisieren). Dieser Ansatz hat eine Reihe von Einschränkungen und es gibt einige Szenarien, in denen es ratsam ist, sich an das eigene App-Back-End zu wenden, wenn ein Gerät seine Registrierung aktualisiert. Das Back-End ruft dann den Benachrichtigungshub auf.

Wenn Sie sich von Ihrem App-Back-End registrieren möchten

Es gibt zwei Szenarien, in denen es ratsam ist, Geräteregistrierungen über Ihr App-Back-End zu weiterleiten.

Tags müssen gesichert werden.

Wenn ein Gerät direkt mit einem Benachrichtigungshub registriert wird, kann er jedes gewünschte Tag angeben. Dies ist kein Problem, wenn Tags öffentliche Interessensgruppen sind, die jedes Gerät abonnieren kann (z. B. Nachrichtenfeeds bezüglich Sportteams). Dies kann jedoch ein Problem sein, wenn einige Tags nur für einige Benutzer verfügbar sind.

Um jeden Benutzer nur für die zulässigen Tags zu registrieren, müssen Sie die Registrierungsvorgänge über ihr eigenes App-Back-End weiterleiten, das die Benutzerauthentifizierung ausführen und die Registrierung für die erforderlichen Tags autorisieren kann.

Das am häufigsten verwendete Beispiel für dieses Szenario verwendet Tags zum Darstellen von Benutzer-IDs. In diesem Fall möchten Sie verhindern, dass Geräte auf Tags registriert werden, die andere Benutzer darstellen, da sie die Benachrichtigungen anderer Benutzer erhalten würden.

Tags werden von Ihrem App-Back-End geändert.

Die Registrierung auf dem Gerät ist bequem und ermöglicht Es Ihnen, Pushbenachrichtigungen und umfangreiches Routing an Interessensgruppen schnell einzurichten. Die Registrierung des Geräts funktioniert jedoch nicht sehr gut, wenn Sie Tags aufgrund von Ereignissen ändern möchten, die auf anderen Geräten auftreten.

Berücksichtigen Sie zwei Szenarien: Wenn die Tags auf dem Smartphone von Alice aufgrund von Ereignissen auf dem Smartphone von Alice festgelegt werden, ist es einfach, die Tags im Benachrichtigungshub zu aktualisieren. Wenn sich Tags andererseits aufgrund von Ereignissen auf anderen Geräten ändern müssen (z. B. der Laptop von Alice beim Anmelden auf einer Website), muss das Gerät darauf warten, dass die App erneut aktiv ist, um die Änderungen im Benachrichtigungshub widerzuspiegeln.

Ein bestimmtes Beispiel für das vorherige Szenario ist eine Musik-App, die eine Weboberfläche und eine mobile App enthält. In diesem Fall kann ein bestimmter Benutzer einer neuen Band über die Website folgen und möchten, dass das Gerät Benachrichtigungen über die neue Band so schnell wie möglich empfangen soll. Ein weiteres Beispiel ist, wenn Tags aus anderen Teilen Ihres Backends (z. B. einem CRM) stammen, der den Status des Benutzers von Silver in Gold ändern kann. Diese Änderung kann dazu führen, dass auf allen Registrierungen aller Benutzer ein neues Tag festgelegt wird.

So registrieren Sie sich aus dem Back-End

Beim Registrieren eines Geräts muss ein Benachrichtigungshub zwischen verschiedenen Geräten unterscheiden. Dies kann nicht nur erreicht werden, indem sie die PNS-Handle betrachten, da sie vorübergehend und nicht eindeutig sind. Um dieses Problem zu lösen, generiert Benachrichtigungshubs lang lebende Registrierungs-IDs, die jedes Gerät lokal speichern muss, um bei jeder Aktualisierung des PNS-Handles, -Tags oder -Vorlage auf seine eigene Registrierung verweisen zu können.

Die folgende Abbildung zeigt den Registrierungsfluss für systemeigene Benachrichtigungen:

  1. Auf dem Gerät, wenn keine Registrierungs-ID lokal gespeichert wird,

    1. Rufen Sie das App-Back-End auf, um die Registrierungs-ID abzurufen.

    2. App-Back-End ruft Benachrichtigungshubs auf, um eine neue Registrierungs-ID zu erstellen und dann die ID wieder auf das Gerät zurückzugeben.

    3. Store die Registrierungs-ID im lokalen Speicher des Geräts.

  2. Rufen Sie auf dem Gerät die Registrierungs-ID aus dem lokalen Speicher ab:

    1. Rufen Sie das App-Back-End auf, indem Sie die Registrierungs-ID, den PNS-Handle und Tags bereitstellen.

    2. Das App-Back-End erstellt oder aktualisiert die entsprechende Registrierung auf dem Benachrichtigungshub.

    3. Wenn das App-Back-End Statuscode 410 zurückgibt, muss eine neue Registrierungs-ID erstellt werden. Löschen Sie die Registrierungs-ID aus dem lokalen Speicher, und starten Sie von Schritt 1 neu.

Backend Registration

Der Fluss für Vorlagenbenachrichtigungen ist analog. Die einzigen Unterschiede sind wie folgt:

  1. Wenn ein Gerät mehrere Vorlagen verwendet, muss es eine Registrierungs-ID pro Vorlage speichern.

  2. Sie können die Vorlagen mithilfe der TemplateName-Eigenschaft der Registrierung identifizieren.

Der folgende Code ist ein Beispiel für Back-End-Endpunkte.

public class RegisterController : ApiController
    {

        private NotificationHubClient hub;

        public RegisterController()
        {
            hub = NotificationHubClient.CreateClientFromConnectionString("Endpoint=sb://buildhub-ns.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=DuWV4SQ08poV6HZly8O/KQNWv3YRTZlExJxu3pNCjGU=", "build2014_2");
        }
        
        public class DeviceRegistration
        {
            public string Platform { get; set; }
            public string Handle { get; set; }
            public string[] Tags { get; set; }
        }

        // POST api/register
        // This creates a registration id
        public async Task<string> Post()
        {
            return await hub.CreateRegistrationIdAsync();
        }

        // PUT api/register/5
        // This creates or updates a registration (with provided PNS handle) at the specified id
        public async void Put(string id, DeviceRegistration deviceUpdate)
        {
            // IMPORTANT: add logic to make sure that caller is allowed to register for the provided tags
            
            RegistrationDescription registration = null;
            switch (deviceUpdate.Platform)
            {
                case "mpns":
                    registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
                    break;
                case "wns":
                    registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
                    break;
                case "apns":
                    registration = new AppleRegistrationDescription(deviceUpdate.Handle);
                    break;
                case "gcm":
                    registration = new GcmRegistrationDescription(deviceUpdate.Handle);
                    break;
                default:
                    throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            registration.RegistrationId = id;
            registration.Tags = new HashSet<string>(deviceUpdate.Tags);

            try
            {
                await hub.CreateOrUpdateRegistrationAsync(registration);
            } catch (MessagingException e) {
                ReturnGoneIfHubResponseIsGone(e);
            }
        }

        // DELETE api/register/5
        public async void Delete(string id)
        {
            await hub.DeleteRegistrationAsync(id);
        }


        private static void ReturnGoneIfHubResponseIsGone(MessagingException e)
        {
            var webex = e.InnerException as WebException;
            if (webex.Status == WebExceptionStatus.ProtocolError)
            {
                var response = (HttpWebResponse)webex.Response;
                if (response.StatusCode == HttpStatusCode.Gone)
                    throw new HttpRequestException(HttpStatusCode.Gone.ToString());
            }
        }
    }

Beachten Sie, dass Sie im vorherigen Code die Logik hinzufügen müssen, um sicherzustellen, dass der Client, der diesen Endpunkt aufruft, für die angeforderten Tags registriert wird. Außerdem kann Ihr Back-End die Tags selbst hinzufügen (z. B. ein Userid-Tag ).

Im folgenden Codebeispiel wird gezeigt, wie Sie die Registrierungsmethode für eine Windows Store-App aus dem Gerät mit den vorherigen Endpunkten implementieren:

class RegisterClient
    {
        private string POST_URL = "{your back-end endpoints}";

        private class DeviceRegistration
        {
            public string Platform { get; set; }
            public string Handle { get; set; }
            public string[] Tags { get; set; }
        }

        public async Task RegisterAsync(string handle, IEnumerable<string> tags)
        {
            var regId = await RetrieveRegistrationIdOrRequestNewOneAsync();

            var deviceRegistration = new DeviceRegistration
            {
                Platform = "wns",
                Handle = handle,
                Tags = tags.ToArray<string>()
            };

            var statusCode = await UpdateRegistrationAsync(regId, deviceRegistration);

            if (statusCode == HttpStatusCode.Gone)
            {
                // regId is expired, deleting from local storage & recreating
                var settings = ApplicationData.Current.LocalSettings.Values;
                settings.Remove("__NHRegistrationId");
                regId = await RetrieveRegistrationIdOrRequestNewOneAsync();
                statusCode = await UpdateRegistrationAsync(regId, deviceRegistration);
            }

            if (statusCode != HttpStatusCode.Accepted)
            {
                // log or throw
            }
        }

        private async Task<HttpStatusCode> UpdateRegistrationAsync(string regId, DeviceRegistration deviceRegistration)
        {
            using (var httpClient = new HttpClient())
            {
                var putUri = POST_URL + "/" + regId;
                var response = await httpClient.PutAsJsonAsync<DeviceRegistration>(putUri, deviceRegistration);
                return response.StatusCode;
            }
        }

        private async Task<string> RetrieveRegistrationIdOrRequestNewOneAsync()
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            if (!settings.ContainsKey("__NHRegistrationId"))
            {
                using (var httpClient = new HttpClient())
                {
                    var response = await httpClient.PostAsync(POST_URL, new StringContent(""));
                    if (response.IsSuccessStatusCode)
                    {
                        string regId = await response.Content.ReadAsStringAsync();
                        regId = regId.Substring(1, regId.Length - 2);
                        settings.Add("__NHRegistrationId", regId);
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
            }
            return (string)settings["__NHRegistrationId"];

        }
    }

Speichern von Registrierungs-IDs in einer Back-End-Datenbank

Manchmal möchten Anwendungen die Registrierungs-IDs im App-Back-End anstelle des lokalen Gerätespeichers beibehalten. Dies geschieht in der Regel, wenn das App-Back-End bereits eine Möglichkeit zum Identifizieren von Geräten hat (z. B. eine InstallationId), und eine Möglichkeit zum Speichern von Geräteinformationen im Back-End-Speicher (z. B. beim Migrieren von einer benutzerdefinierten Pushlösung, in der PNS-Handle gespeichert wurden).

So ändern Sie Tags aus dem Back-End

Wenn Sie Tags aus dem Back-End ändern möchten, müssen Sie eine Möglichkeit für das Back-End haben, um die Registrierungen zu identifizieren, die geändert werden sollen. Dies erfolgt in der Regel mithilfe eines Tags.

Angenommen, es gibt eine Musik-App, in der ein Benutzer eine neue Favoritenband aus dem Web hinzufügt, und das Back-End fügt ein Tag in die mobilen Registrierungen des Benutzers hinzu. In diesem Fall verwendet die App ein Tag, um den Benutzer zu identifizieren, und verwendet dann dieses Tag, um die Registrierungen abzurufen, die aktualisiert und aktualisiert werden sollen.

Im folgenden Codebeispiel werden die Registrierungen abgerufen und ein neues Tag hinzugefügt.

var registrations = await hub.GetRegistrationsByTagAsync("{userId}", 10);
            foreach (var reg in registrations)
            {
                reg.Tags.Add("{newBand}");
                await hub.UpdateRegistrationAsync(reg);
            }

Beachten Sie, dass in diesem Beispiel, wenn Sie Vorlagen verwenden, davon ausgegangen wird, dass Sie das Tag auf allen Ihren Vorlagen hinzufügen.