Registratiebeheer

In dit onderwerp wordt uitgelegd hoe u apparaten registreert bij Notification Hubs om pushmeldingen te ontvangen. In het onderwerp worden registraties op hoog niveau beschreven. Vervolgens worden de twee belangrijkste patronen voor het registreren van apparaten geïntroduceerd: registreren vanaf het apparaat rechtstreeks bij de Notification Hub en registreren via een toepassingsback-end.

Wat is apparaatregistratie?

Apparaatregistratie met een Notification Hub wordt uitgevoerd met behulp van een registratie of installatie.

Registraties

Een registratie koppelt de PNS-ingang (Platform Notification Service) voor een apparaat met tags en mogelijk een sjabloon. De PNS-ingang kan een ChannelURI of apparaattokenregistratie-id zijn. Tags worden gebruikt om meldingen te routeren naar de juiste set apparaatingangen. Zie Routering en tagexpressies voor meer informatie. Sjablonen worden gebruikt om transformatie per registratie te implementeren. Zie Sjablonen voor meer informatie.

Notitie

Azure Notification Hubs ondersteunt maximaal 60 tags per apparaat.

Installaties

Een installatie is een verbeterde registratie die een verzameling push-gerelateerde eigenschappen bevat. Het is de nieuwste en beste methode voor het registreren van uw apparaten met behulp van de .NET SDK aan de serverzijde (Notification Hub SDK voor back-endbewerkingen). U kunt ook de Rest API-methode van Notification Hubs gebruiken om installaties op het clientapparaat zelf te registreren. Als u een back-endservice gebruikt, moet u de Notification Hub SDK kunnen gebruiken voor back-endbewerkingen.

Hier volgen enkele belangrijke voordelen van het gebruik van installaties:

  • Het maken of bijwerken van een installatie is volledig idempotent. U kunt het dus opnieuw proberen zonder dat u zich zorgen hoeft te maken over dubbele registraties.
  • Het installatiemodel ondersteunt een speciale tagindeling ($InstallationId:{INSTALLATION_ID}) waarmee een melding rechtstreeks naar het specifieke apparaat kan worden verzonden. Als de code van de app bijvoorbeeld een installatie-id van joe93developer instelt voor dit specifieke apparaat, kan een ontwikkelaar zich richten op dit apparaat wanneer een melding naar de $InstallationId:{joe93developer} tag wordt verzonden. Hierdoor kunt u zich richten op een specifiek apparaat zonder dat u extra codering hoeft uit te voeren.
  • Met behulp van installaties kunt u ook gedeeltelijke registratie-updates uitvoeren. De gedeeltelijke update van een installatie wordt aangevraagd met een PATCH-methode met behulp van de JSON-Patch-standaard. Dit is handig als u tags voor de registratie wilt bijwerken. U hoeft niet de hele registratie te verwijderen en vervolgens alle vorige tags opnieuw te verzenden.

Een installatie kan de volgende eigenschappen bevatten. Zie Een installatie maken of overschrijven met REST API of Installatie-eigenschappen voor een volledige lijst van de installatie-eigenschappen.

// Example installation format to show some supported properties
{
    installationId: "",
    expirationTime: "",
    tags: [],
    platform: "",
    pushChannel: "",
    ………
    templates: {
        "templateName1" : {
            body: "",
            tags: [] },
        "templateName2" : {
            body: "",
            // Headers are for Windows Store only
            headers: {
                "X-WNS-Type": "wns/tile" }
            tags: [] }
    },
    secondaryTiles: {
        "tileId1": {
            pushChannel: "",
            tags: [],
            templates: {
                "otherTemplate": {
                    bodyTemplate: "",
                    headers: {
                        ... }
                    tags: [] }
            }
        }
    }
}

Notitie

Standaard verlopen registraties en installaties niet.

Registraties en installaties moeten een geldige PNS-ingang bevatten voor elk apparaat/kanaal. Omdat PNS-ingangen alleen kunnen worden verkregen in een client-app op het apparaat, is één patroon om rechtstreeks op dat apparaat te registreren met de client-app. Aan de andere kant kunnen beveiligingsoverwegingen en bedrijfslogica met betrekking tot tags vereisen dat u apparaatregistratie in de back-end van de app beheert.

Wanneer de push wordt uitgevoerd naar een ingang die is verlopen door de PNS, wordt de bijbehorende installatie-/registratierecord automatisch opgeschoond in Azure Notification Hubs op basis van het antwoord dat is ontvangen van de PNS-server. Als u verlopen records van een secundaire Notification Hub wilt opschonen, voegt u aangepaste logica toe waarmee feedback van elke verzender wordt verwerkt. Vervolgens verloopt de installatie/registratie in de secundaire Notification Hub.

Notitie

De Installaties-API biedt geen ondersteuning voor de Baidu-service (hoewel de Api voor registraties wel).

Sjablonen

Als u Sjablonen wilt gebruiken, bevat de installatie van het apparaat ook alle sjablonen die aan dat apparaat zijn gekoppeld in een JSON-indeling (zie het bovenstaande voorbeeld). Met de sjabloonnamen kunt u verschillende sjablonen voor hetzelfde apparaat gebruiken.

Elke sjabloonnaam wordt toegewezen aan een sjabloontekst en een optionele set tags. Bovendien kan elk platform aanvullende sjablooneigenschappen hebben. Voor Windows Store (met WNS) kan een extra set headers deel uitmaken van de sjabloon. In het geval van APNs kunt u een verloopeigenschap instellen op een constante of op een sjabloonexpressie. Zie het onderwerp Een installatie maken of overschrijven met REST voor een volledige lijst van de installatie-eigenschappen.

Secundaire tegels voor Windows Store-apps

Voor Windows Store-clienttoepassingen is het verzenden van meldingen naar secundaire tegels hetzelfde als het verzenden van meldingen naar de primaire tegel. Dit wordt ook ondersteund in installaties. Secundaire tegels hebben een andere ChannelUri, die de SDK in uw client-app transparant verwerkt.

De SecondaryTiles-woordenlijst gebruikt dezelfde TileId die wordt gebruikt voor het maken van het object SecondaryTiles in uw Windows Store-app. Net als bij de primaire ChannelUri kunnen ChannelUris van secundaire tegels op elk moment worden gewijzigd. Als u de installaties in de Notification Hub bijgewerkt wilt houden, moet het apparaat deze vernieuwen met de huidige ChannelUris van de secundaire tegels.

Registratiebeheer vanaf het apparaat

Bij het beheren van apparaatregistratie vanuit client-apps is de back-end alleen verantwoordelijk voor het verzenden van meldingen. Client-apps houden PNS-handles up-to-date en registreren tags. In de volgende afbeelding ziet u dit patroon.

Registratie vanaf apparaat

Het apparaat haalt eerst de PNS-ingang op uit de PNS en registreert zich vervolgens rechtstreeks bij de Notification Hub. Nadat de registratie is geslaagd, kan de back-end van de app een melding verzenden die gericht is op die registratie. Zie Routering en tagexpressies voor meer informatie over het verzenden van meldingen.

In dit geval gebruikt u alleen listen-rechten voor toegang tot uw Notification Hubs vanaf het apparaat. Zie Beveiliging voor meer informatie.

Registreren vanaf het apparaat is de eenvoudigste methode, maar het heeft enkele nadelen:

  • Een client-app kan de tags alleen bijwerken wanneer de app actief is. Als een gebruiker bijvoorbeeld twee apparaten heeft die tags registreren die betrekking hebben op sportteams, en het eerste apparaat zich registreert voor een extra tag (bijvoorbeeld Seahawks), ontvangt het tweede apparaat de meldingen over de Seahawks niet totdat de app op het tweede apparaat een tweede keer wordt uitgevoerd. Meer in het algemeen geldt dat wanneer tags worden beïnvloed door meerdere apparaten, het beheer van tags vanuit de back-end een wenselijke optie is.
  • Omdat apps kunnen worden gehackt, vereist het beveiligen van de registratie voor specifieke tags extra zorg, zoals wordt uitgelegd in het artikel Beveiliging.

Voorbeeldcode voor registratie bij een Notification Hub vanaf een apparaat met behulp van een installatie

Op dit moment wordt dit alleen ondersteund met behulp van de Notification Hubs REST API.

U kunt ook de PATCH-methode gebruiken met behulp van de JSON-Patch-standaard voor het bijwerken van de installatie.

class DeviceInstallation
{
    public string installationId { get; set; }
    public string platform { get; set; }
    public string pushChannel { get; set; }
    public string[] tags { get; set; }

    private async Task<HttpStatusCode> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation,
        string hubName, string listenConnectionString)
    {
        if (deviceInstallation.installationId == null)
            return HttpStatusCode.BadRequest;

        // Parse connection string (https://msdn.microsoft.com/library/azure/dn495627.aspx)
        ConnectionStringUtility connectionSaSUtil = new ConnectionStringUtility(listenConnectionString);
        string hubResource = "installations/" + deviceInstallation.installationId + "?";
        string apiVersion = "api-version=2015-04";

        // Determine the targetUri that we will sign
        string uri = connectionSaSUtil.Endpoint + hubName + "/" + hubResource + apiVersion;

        //=== Generate SaS Security Token for Authorization header ===
        // See https://msdn.microsoft.com/library/azure/dn495627.aspx
        string SasToken = connectionSaSUtil.getSaSToken(uri, 60);

        using (var httpClient = new HttpClient())
        {
            string json = JsonConvert.SerializeObject(deviceInstallation);

            httpClient.DefaultRequestHeaders.Add("Authorization", SasToken);

            var response = await httpClient.PutAsync(uri, new StringContent(json, System.Text.Encoding.UTF8, "application/json"));
            return response.StatusCode;
        }
    }

    var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

    string installationId = null;
    var settings = ApplicationData.Current.LocalSettings.Values;

    // If we have not stored an installation ID in application data, create and store as application data.
    if (!settings.ContainsKey("__NHInstallationId"))
    {
        installationId = Guid.NewGuid().ToString();
        settings.Add("__NHInstallationId", installationId);
    }

    installationId = (string)settings["__NHInstallationId"];

    var deviceInstallation = new DeviceInstallation
    {
        installationId = installationId,
        platform = "wns",
        pushChannel = channel.Uri,
        //tags = tags.ToArray<string>()
    };

    var statusCode = await CreateOrUpdateInstallationAsync(deviceInstallation, 
                    "<HUBNAME>", "<SHARED LISTEN CONNECTION STRING>");

    if (statusCode != HttpStatusCode.Accepted)
    {
        var dialog = new MessageDialog(statusCode.ToString(), "Registration failed. Installation Id : " + installationId);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
    else
    {
        var dialog = new MessageDialog("Registration successful using installation Id : " + installationId);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
}

Voorbeeldcode voor registratie bij een Notification Hub vanaf een apparaat met behulp van een registratie

Met deze methoden wordt een registratie gemaakt of bijgewerkt voor het apparaat waarop ze worden aangeroepen. Dit betekent dat u de volledige registratie moet overschrijven om de ingang of de tags bij te werken. Houd er rekening mee dat registraties tijdelijk zijn, dus u moet altijd een betrouwbare opslag hebben met de huidige tags die een specifiek apparaat nodig heeft.

// Initialize the Notification Hub
NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(listenConnString, hubName);

// The Device ID from the PNS
var pushChannel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

// If you are registering from the client itself, then store this registration ID in device
// storage. Then when the app starts, you can check if a registration ID already exists or not before
// creating.
var settings = ApplicationData.Current.LocalSettings.Values;

// If we have not stored a registration ID in application data, store in application data.
if (!settings.ContainsKey("__NHRegistrationId"))
{
    // make sure there are no existing registrations for this push handle (used for iOS and Android)    
    string newRegistrationId = null;
    var registrations = await hub.GetRegistrationsByChannelAsync(pushChannel.Uri, 100);
    foreach (RegistrationDescription registration in registrations)
    {
        if (newRegistrationId == null)
        {
            newRegistrationId = registration.RegistrationId;
        }
        else
        {
            await hub.DeleteRegistrationAsync(registration);
        }
    }

    newRegistrationId = await hub.CreateRegistrationIdAsync();

    settings.Add("__NHRegistrationId", newRegistrationId);
}

string regId = (string)settings["__NHRegistrationId"];

RegistrationDescription registration = new WindowsRegistrationDescription(pushChannel.Uri);
registration.RegistrationId = regId;
registration.Tags = new HashSet<string>(YourTags);

try
{
    await hub.CreateOrUpdateRegistrationAsync(registration);
}
catch (Microsoft.WindowsAzure.Messaging.RegistrationGoneException e)
{
    settings.Remove("__NHRegistrationId");
}

Registratiebeheer vanuit een back-end

Voor het beheren van registraties vanuit de back-end is het schrijven van extra code vereist. De app van het apparaat moet de bijgewerkte PNS-ingang aan de back-end leveren telkens wanneer de app wordt gestart (samen met tags en sjablonen), en de back-end moet deze ingang bijwerken op de Notification Hub. In de volgende afbeelding ziet u dit ontwerp.

Registratiebeheer

De voordelen van het beheren van registraties vanuit de back-end zijn de mogelijkheid om tags te wijzigen voor registraties, zelfs wanneer de bijbehorende app op het apparaat inactief is, en om de client-app te verifiëren voordat een tag aan de registratie wordt toegevoegd.

Voorbeeldcode voor registratie bij een Notification Hub vanuit een back-end met behulp van een installatie

Het clientapparaat krijgt nog steeds de PNS-ingang en relevante installatie-eigenschappen zoals voorheen en roept een aangepaste API aan op de back-end die de registratie kan uitvoeren en tags kan autoriseren, enzovoort. De back-end kan gebruikmaken van de Notification Hub SDK voor back-endbewerkingen.

U kunt ook de PATCH-methode gebruiken met behulp van de JSON-Patch-standaard voor het bijwerken van de installatie.

// Initialize the Notification Hub
NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(listenConnString, hubName);

// Custom API on the backend
public async Task<HttpResponseMessage> Put(DeviceInstallation deviceUpdate)
{

    Installation installation = new Installation();
    installation.InstallationId = deviceUpdate.InstallationId;
    installation.PushChannel = deviceUpdate.Handle;
    installation.Tags = deviceUpdate.Tags;

    switch (deviceUpdate.Platform)
    {
        case "wns":
            installation.Platform = NotificationPlatform.Wns;
            break;
        case "apns":
            installation.Platform = NotificationPlatform.Apns;
            break;
        case "fcm":
            installation.Platform = NotificationPlatform.Fcm;
            break;
        default:
            throw new HttpResponseException(HttpStatusCode.BadRequest);
    }


    // In the backend we can control if a user is allowed to add tags
    //installation.Tags = new List<string>(deviceUpdate.Tags);
    //installation.Tags.Add("username:" + username);

    await hub.CreateOrUpdateInstallationAsync(installation);

    return Request.CreateResponse(HttpStatusCode.OK);
}

Voorbeeldcode voor registratie met een Notification Hub vanuit een back-end met behulp van een registratie-id

Vanuit uw app-back-end kunt u eenvoudige CRUDS-bewerkingen uitvoeren op registraties. Bijvoorbeeld:

var hub = NotificationHubClient.CreateClientFromConnectionString("{connectionString}", "hubName");

// create a registration description object of the correct type, e.g.
var reg = new WindowsRegistrationDescription(channelUri, tags);

// Create
await hub.CreateRegistrationAsync(reg);

// Get by ID
var r = await hub.GetRegistrationAsync<RegistrationDescription>("id");

// update
r.Tags.Add("myTag");

// update on hub
await hub.UpdateRegistrationAsync(r);

// delete
await hub.DeleteRegistrationAsync(r);

De back-end moet gelijktijdigheid tussen registratie-updates afhandelen. Service Bus biedt optimistisch gelijktijdigheidsbeheer voor registratiebeheer. Op HTTP-niveau wordt dit geïmplementeerd met het gebruik van ETag voor registratiebeheerbewerkingen. Deze functie wordt transparant gebruikt door Microsoft SDK's, die een uitzondering genereren als een update wordt geweigerd om gelijktijdigheidsredenen. De back-end van de app is verantwoordelijk voor het verwerken van deze uitzonderingen en het opnieuw proberen van de update, indien nodig.