Mendaftar dari Backend Aplikasi Anda

Seperti disebutkan di bagian sebelumnya, perangkat harus membuat satu atau beberapa pendaftaran di hub pemberitahuan untuk menerima pemberitahuan push. Salah satu cara untuk menyelesaikan pendaftaran ini adalah dengan meminta perangkat seluler menghubungi hub pemberitahuan secara langsung untuk menentukan (atau memperbarui) handel PNS mereka dan tag mereka. Pendekatan ini memiliki sejumlah batasan dan ada beberapa skenario di mana disarankan untuk menghubungi backend aplikasi Anda sendiri saat perangkat merefresh pendaftarannya. Backend kemudian memanggil hub pemberitahuan.

Kapan harus mendaftar dari backend aplikasi Anda

Ada dua skenario di mana disarankan untuk merutekan pendaftaran perangkat melalui backend aplikasi Anda.

Tag harus diamankan

Saat perangkat mendaftar langsung dengan hub pemberitahuan, perangkat dapat menentukan tag apa pun yang diinginkannya. Ini bukan masalah jika tag adalah grup minat publik yang dapat berlangganan perangkat apa pun (misalnya, umpan berita mengenai tim olahraga). Namun, ini bisa menjadi masalah ketika beberapa tag hanya tersedia untuk beberapa pengguna.

Untuk mendaftarkan setiap pengguna hanya ke tag yang diizinkan, Anda harus merutekan operasi pendaftaran melalui backend aplikasi Anda sendiri, yang dapat melakukan autentikasi pengguna dan mengotorisasi pendaftaran untuk tag yang diperlukan.

Contoh paling umum dari skenario ini adalah menggunakan tag untuk mewakili ID pengguna. Dalam hal ini, Anda ingin mencegah perangkat mendaftar ke tag yang mewakili pengguna lain, karena mereka akan menerima pemberitahuan pengguna lain tersebut.

Tag dimodifikasi oleh backend aplikasi Anda

Mendaftar dari perangkat nyaman dan memungkinkan Anda untuk dengan cepat menyiapkan pemberitahuan push dan perutean yang kaya ke grup minat. Namun, mendaftar dari perangkat tidak berfungsi dengan baik jika Anda ingin mengubah tag sebagai akibat dari peristiwa yang terjadi pada perangkat lain.

Pertimbangkan dua skenario: jika tag di ponsel Alice diatur sebagai akibat dari peristiwa yang terjadi di ponsel Alice, maka mudah bagi aplikasi untuk memperbarui tag di hub pemberitahuan. Jika, di sisi lain, tag harus berubah sebagai akibat dari peristiwa yang terjadi di perangkat lain (misalnya, laptop Alice saat masuk ke situs web), maka perangkat harus menunggu aplikasi aktif lagi untuk mencerminkan perubahan di hub pemberitahuan.

Contoh spesifik dari skenario sebelumnya adalah aplikasi musik yang mencakup pengalaman web, dan aplikasi seluler. Dalam hal ini, pengguna tertentu mungkin mengikuti band baru melalui situs web, dan ingin perangkat mulai menerima pemberitahuan tentang band baru sesegera mungkin. Contoh lain adalah ketika tag berasal dari bagian lain dari backend Anda (CRM, misalnya), yang dapat mengubah status pengguna dari Silver ke Gold. Perubahan ini dapat mengakibatkan tag baru diatur pada semua pendaftaran pengguna.

Cara mendaftar dari backend

Saat mendaftarkan perangkat, hub pemberitahuan harus membedakan antara perangkat yang berbeda. Ini tidak dapat dicapai hanya dengan melihat handel PNS, karena bersifat sementara dan tidak unik. Untuk mengatasi masalah ini, Notification Hubs menghasilkan ID pendaftaran berumur panjang yang harus disimpan setiap perangkat secara lokal agar dapat merujuk ke pendaftarannya sendiri setiap kali memperbarui handel, tag, atau templat PNS-nya.

Gambar berikut menunjukkan alur pendaftaran untuk pemberitahuan asli:

  1. Pada perangkat, jika tidak ada id pendaftaran yang disimpan secara lokal,

    1. Hubungi backend aplikasi untuk mendapatkan id pendaftaran.

    2. App backend memanggil hub pemberitahuan untuk membuat ID pendaftaran baru, lalu mengembalikan ID kembali ke perangkat.

    3. Simpan ID pendaftaran di penyimpanan lokal perangkat.

  2. Di perangkat, ambil ID pendaftaran dari penyimpanan lokal:

    1. Panggil backend aplikasi, berikan ID pendaftaran, handel PNS, dan tag.

    2. Backend aplikasi membuat atau memperbarui pendaftaran yang sesuai di hub pemberitahuan.

    3. Jika backend aplikasi mengembalikan kode status 410, maka id pendaftaran baru harus dibuat. Hapus ID pendaftaran dari penyimpanan lokal dan mulai ulang dari langkah 1.

Backend Registration

Alur untuk pemberitahuan templat dianalogikan. Satu-satunya perbedaan adalah sebagai berikut:

  1. Jika perangkat menggunakan beberapa templat, maka perangkat harus menyimpan satu ID pendaftaran per templat.

  2. Anda dapat mengidentifikasi templat dengan menggunakan properti TemplateName pendaftaran.

Kode berikut adalah contoh titik akhir back-end.

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

Perhatikan bahwa dalam kode sebelumnya, Anda harus menambahkan logika untuk memastikan bahwa klien yang memanggil titik akhir tersebut berwenang untuk mendaftar untuk tag yang diminta. Selain itu, backend Anda dapat menambahkan tag itu sendiri (misalnya, tag userid ).

Contoh kode berikut menunjukkan cara menerapkan metode pendaftaran untuk aplikasi Windows Store, dari perangkat, dengan titik akhir sebelumnya:

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

        }
    }

Menyimpan ID pendaftaran dalam database back-end

Terkadang, aplikasi ingin menyimpan ID pendaftaran di backend aplikasi alih-alih di penyimpanan lokal perangkat. Ini biasanya terjadi ketika backend aplikasi sudah memiliki cara untuk mengidentifikasi perangkat (misalnya, installationId), dan cara untuk menyimpan informasi perangkat di penyimpanan backend (misalnya, saat bermigrasi dari solusi pendorongan kustom tempat penanganan PNS disimpan).

Cara mengubah tag dari backend

Jika Anda ingin memodifikasi tag dari backend, Anda harus memiliki cara agar backend mengidentifikasi pendaftaran yang akan dimodifikasi. Ini biasanya dilakukan menggunakan tag.

Misalnya, asumsikan ada aplikasi musik di mana pengguna menambahkan band favorit baru dari Web, dan backend menambahkan tag di pendaftaran seluler pengguna sebagai akibatnya. Dalam hal ini, aplikasi menggunakan tag untuk mengidentifikasi pengguna, lalu menggunakan tag tersebut untuk mengambil pendaftaran yang akan diperbarui dan memperbaruinya.

Contoh kode berikut mengambil pendaftaran, dan menambahkan tag baru ke dalamnya.

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

Perhatikan bahwa dalam contoh ini, jika Anda menggunakan templat, kami berasumsi bahwa Anda menambahkan tag di semua templat Anda.