Share via


Regisztráció az alkalmazás háttérrendszeréből

Ahogy az előző szakaszokban említettük, az eszközöknek létre kell hozniuk egy vagy több regisztrációt egy értesítési központban a leküldéses értesítések fogadásához. A regisztráció befejezésének egyik módja, ha a mobileszközök közvetlenül az értesítési központhoz fordulnak, hogy megadják (vagy frissítsék) a PNS-leírójukat és címkéiket. Ez a megközelítés számos korlátozással rendelkezik, és vannak olyan esetek, amikor célszerű kapcsolatba lépni a saját alkalmazás háttérrendszerével, amikor egy eszköz frissíti a regisztrációját. A háttérrendszer ezután meghívja az értesítési központot.

Mikor kell regisztrálni az alkalmazás háttérrendszeréből?

Az eszközregisztrációkat két forgatókönyvben célszerű az alkalmazás háttérrendszerén keresztül irányítani.

A címkéket védeni kell

Amikor egy eszköz közvetlenül regisztrál egy értesítési központban, megadhatja a kívánt címkét. Ez nem jelent problémát, ha a címkék olyan közérdekű csoportok, amelyekre bármely eszköz előfizethet (például sportcsapatokkal kapcsolatos hírcsatornák). Ez azonban problémát okozhat, ha egyes címkék csak bizonyos felhasználók számára érhetők el.

Ha minden felhasználót csak az engedélyezett címkékre szeretne regisztrálni, a regisztrációs műveleteket a saját alkalmazás háttérrendszerén kell irányítania, amely képes felhasználói hitelesítést végezni, és engedélyezni a regisztrációt a szükséges címkékhez.

Erre a forgatókönyvre a leggyakoribb példa a címkék használata a felhasználói azonosítók ábrázolására. Ebben az esetben meg szeretné akadályozni, hogy az eszközök olyan címkékre regisztráljanak, amelyek más felhasználókat jelölnek, mivel ők kapnák meg a másik felhasználó értesítéseit.

A címkéket az alkalmazás háttérrendszere módosítja

Az eszközről való regisztrálás kényelmes, és lehetővé teszi a leküldéses értesítések gyors beállítását és az érdeklődési csoportoknak való részletes útválasztást. Az eszközről való regisztráció azonban nem működik jól, ha más eszközökön előforduló események miatt szeretné módosítani a címkéket.

Fontolja meg két forgatókönyvet: ha Alice telefonján a címkék alice telefonján történt események miatt vannak beállítva, akkor az alkalmazás egyszerűen frissítheti a címkéket az értesítési központban. Ha viszont a címkéknek más eszközökön (például Alice laptopján, amikor bejelentkeztek egy webhelyre), akkor az eszköznek meg kell várnia, hogy az alkalmazás újra aktív legyen, hogy tükrözze az értesítési központ változásait.

Az előző forgatókönyv egy konkrét példája egy webes felületet és egy mobilalkalmazást tartalmazó zenealkalmazás. Ebben az esetben előfordulhat, hogy egy adott felhasználó egy új sávot követ a webhelyen keresztül, és azt szeretné, hogy az eszköz a lehető leghamarabb értesítést kapjon az új sávról. Egy másik példa, amikor a címkék a háttérrendszer más részeiből származnak (például CRM), amely megváltoztathatja a felhasználó állapotát Silverről Goldra. Ez a módosítás azt eredményezheti, hogy új címke lesz beállítva az összes felhasználó regisztrációján.

Regisztráció a háttérrendszerből

Az eszköz regisztrálásakor az értesítési központnak különbséget kell tennie a különböző eszközök között. Ez nem valósítható meg csak a PNS-leírók megtekintésével, mivel átmenetiek és nem egyediek. A probléma megoldásához a Notification Hubs olyan hosszú élettartamú regisztrációs azonosítókat hoz létre, amelyeket minden eszköznek helyileg kell tárolnia ahhoz, hogy minden alkalommal hivatkozhasson a saját regisztrációjára, amikor frissíti a PNS-leírót, a címkéket vagy a sablont.

Az alábbi ábrán a natív értesítések regisztrációs folyamata látható:

  1. Ha az eszközön nincs helyileg tárolva regisztrációs azonosító,

    1. Hívja meg az alkalmazás háttérrendszerét a regisztrációs azonosító lekéréséhez.

    2. Az alkalmazás háttérrendszere meghívja az értesítési központokat egy új regisztrációs azonosító létrehozásához, majd visszaadja az azonosítót az eszköznek.

    3. Tárolja a regisztrációs azonosítót az eszköz helyi tárolójában.

  2. Az eszközön kérje le a regisztrációs azonosítót a helyi tárolóból:

    1. Hívja meg az alkalmazás háttérrendszerét, adja meg a regisztrációs azonosítót, a PNS-leírót és a címkéket.

    2. Az alkalmazás háttérrendszere létrehozza vagy frissíti a megfelelő regisztrációt az értesítési központban.

    3. Ha az alkalmazás háttérrendszere a 410-et adja vissza, akkor létre kell hozni egy új regisztrációs azonosítót. Törölje a regisztrációs azonosítót a helyi tárolóból, és indítsa újra az 1. lépéstől.

Backend Registration

A sablonértesítések folyamata hasonló. Az egyetlen különbség a következő:

  1. Ha egy eszköz több sablont használ, akkor sablononként egy regisztrációs azonosítót kell tárolnia.

  2. A sablonokat a regisztráció TemplateName tulajdonságával azonosíthatja.

Az alábbi kód egy példa a háttérbeli végpontokra.

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

Vegye figyelembe, hogy az előző kódban hozzá kell adnia a logikát, hogy a végpontot hívó ügyfél regisztrálhasson a kért címkékre. Emellett a háttérrendszer is hozzáadhatja magát a címkéket (például egy userid címkét).

Az alábbi példakód bemutatja, hogyan implementálhatja egy Windows Store-alkalmazás regisztrációs módszerét az eszközről az előző végpontokkal:

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"];

        }
    }

Regisztrációs azonosítók tárolása háttéradatbázisban

Előfordulhat, hogy az alkalmazások nem az eszköz helyi tárhelyén, hanem az alkalmazás háttérrendszerében szeretnék tárolni a regisztrációs azonosítókat. Ez általában akkor fordul elő, ha az alkalmazás háttérrendszere már rendelkezik az eszközök azonosításának módjával (például egy installationId azonosítóval), valamint az eszközadatok háttértárban való tárolásának módjával (például pNS-leírókat tároló egyéni leküldéses megoldásból való migráláskor).

Címkék módosítása a háttérrendszerből

Ha módosítani szeretné a háttérrendszer címkéit, a háttérrendszernek módot kell adnia a módosítani kívánt regisztrációk azonosítására. Ez általában címke használatával történik.

Tegyük fel például, hogy van egy zenealkalmazás, amelyben egy felhasználó új kedvenc sávot ad hozzá az internetről, és a háttérrendszer ennek eredményeképpen hozzáad egy címkét a felhasználó mobilregisztrációihoz. Ebben az esetben az alkalmazás egy címkével azonosítja a felhasználót, majd ezt a címkét használja a frissítendő regisztrációk lekéréséhez és frissítéséhez.

Az alábbi példakód lekéri a regisztrációkat, és új címkét ad hozzájuk.

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

Vegye figyelembe, hogy ebben a példában, ha sablonokat használ, feltételezzük, hogy az összes sablonhoz hozzáadja a címkét.