Поделиться через


Управление регистрацией

В этом разделе объясняется, как зарегистрировать устройства в центрах уведомлений для получения push-уведомлений. В этом разделе описываются регистрации на высоком уровне, а затем представлены два основных шаблона регистрации устройств: регистрация с устройства непосредственно в концентраторе уведомлений и регистрация через серверную часть приложения.

Что такое регистрация устройств

Регистрация устройств в Центре уведомлений выполняется с помощью регистрации или установки.

Регистрации

Регистрация связывает идентификатор службы уведомлений платформы (PNS) для устройства с тегами и шаблоном, если таковой имеется. Дескриптор PNS может быть каналом URI или идентификатором регистрации маркера устройства. Теги используются для маршрутизации уведомлений в правильный набор дескрипторов устройств. Дополнительные сведения см. в статье Маршрутизация и выражения тегов. Шаблоны используются для реализации преобразования для каждого отдельного случая регистрации. Дополнительные сведения см. в разделе "Шаблоны".

Примечание.

Центры уведомлений Azure поддерживают не более 60 тегов на устройство.

Установки

Установка — это расширенная регистрация, которая включает пакет свойств, связанных с push-уведомлениями. Это последний и лучший подход к регистрации устройств с помощью серверного пакета SDK для .NET (пакет SDK центра уведомлений для внутренних операций). Вы также можете использовать подход REST API Центров уведомлений для регистрации установок на самом клиентском устройстве. Если вы используете серверную службу, вы сможете использовать пакет SDK центра уведомлений для внутренних операций.

Ниже приведены некоторые основные преимущества использования установок.

  • Создание или обновление установки полностью идемпотентно. Таким образом, вы можете повторить попытку без каких-либо проблем с повторяющимися регистрациями.
  • Модель установки поддерживает специальный формат тега ($InstallationId:{INSTALLATION_ID}), который позволяет отправлять уведомление непосредственно конкретному устройству. Например, если код приложения задает идентификатор установки для этого конкретного joe93developer устройства, разработчик может нацелиться на это устройство при отправке уведомления $InstallationId:{joe93developer} в тег. Это позволяет нацеливать определенное устройство, не выполняя дополнительное кодирование.
  • Использование установок также позволяет выполнять частичные обновления регистрации. Частичное обновление установки запрашивается с помощью метода PATCH с помощью стандартаJSON-Patch. Это полезно, когда вы хотите обновить теги регистрации. Вам не нужно снова вытягивать всю регистрацию, а затем повторно отправлять все предыдущие теги.

Установка может содержать следующие свойства. Полный список свойств установки см. в разделе "Создание или перезапись установки" с помощью REST API или свойств установки.

// 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: [] }
            }
        }
    }
}

Примечание.

По умолчанию срок действия регистрации и установки не истекает.

Регистрации и установки должны содержать действительный PNS-дескриптор для каждого устройства или канала. Так как дескриптор PNS можно получить только в клиентском приложении на устройстве, один шаблон — зарегистрировать непосредственно на этом устройстве в клиентском приложении. С другой стороны, рекомендации по безопасности и бизнес-логика, связанные с тегами, могут потребовать управления регистрацией устройств в серверной части приложения.

При отправке уведомления на дескриптор, срок действия которого истек по определению PNS, Центры уведомлений Azure автоматически очищают связанную запись установки и регистрации на основе ответа, полученного от сервера PNS. Чтобы очистить истекшие записи из дополнительного концентратора уведомлений, добавьте пользовательскую логику, которая обрабатывает отзывы от каждой отправки. Затем истекает срок действия установки и регистрации в дополнительном центре уведомлений.

Примечание.

API инсталляций не поддерживает службу Baidu (хотя API регистрации поддерживает).

Шаблоны

Если вы хотите использовать шаблоны, установка устройства также содержит все шаблоны, связанные с этим устройством в формате JSON (см. пример выше). Имена шаблонов помогают нацеливать разные шаблоны для одного устройства.

Каждое имя шаблона сопоставляется с текстом шаблона и необязательным набором тегов. Кроме того, каждая платформа может иметь дополнительные свойства шаблона. Для Магазина Windows (с помощью WNS) дополнительный набор заголовков может быть частью шаблона. В случае APNs можно задать свойство истечения срока действия константой или выражением шаблона. Полный список свойств установки см. в разделе "Создание или перезапись установки" в разделе REST .

Вторичные плитки для приложений Магазина Windows

Для клиентских приложений Магазина Windows отправка уведомлений на вторичные плитки совпадает с отправкой их в основной. Это также поддерживается в установках. Вторичные плитки имеют другой канал ChannelUri, который пакет SDK для клиентского приложения обрабатывает прозрачно.

Словарь SecondaryTiles использует тот же идентификатор TileId, который используется для создания объекта SecondaryTiles в приложении Windows Store. Как и в случае с основным ChannelUri, ChannelUris вторичных плиток может изменяться в любой момент. Для того чтобы поддерживать установки в центре уведомлений актуальными, устройство должно обновлять их, используя текущие ChannelUris вторичных плиток.

Управление регистрацией с устройства

При управлении регистрацией устройств из клиентских приложений серверная часть отвечает только за отправку уведомлений. Клиентские приложения сохраняют дескрипторы PNS up-to-date и регистрируют теги. На следующем рисунке показан этот шаблон.

Регистрация с устройства

Устройство сначала извлекает дескриптор PNS из PNS, а затем регистрируется непосредственно в концентраторе уведомлений. После успешной регистрации серверная часть приложения может отправить уведомление, предназначенное для этой регистрации. Дополнительные сведения о отправке уведомлений см. в разделе "Выражения маршрутизации и тегов".

В этом случае вы используете только права прослушивания для доступа к центрам уведомлений с устройства. Дополнительные сведения см. в разделе Безопасность.

Регистрация с устройства является самым простым методом, но имеет некоторые недостатки:

  • Клиентское приложение может обновлять теги только в том случае, если приложение активно. Например, если у пользователя есть два устройства, которые регистрируют теги, связанные с спортивными командами, при регистрации первого устройства для дополнительного тега (например, Seahawks), второе устройство не получит уведомления о Seahawks, пока приложение на втором устройстве не будет выполнено во второй раз. Как правило, если теги влияют на несколько устройств, управление тегами из серверной части является желательным вариантом.
  • Так как приложения можно взломать, защита регистрации для определенных тегов требует дополнительной помощи, как описано в статье "Безопасность".

Пример кода для регистрации в центре уведомлений с устройства с помощью установки

В настоящее время это поддерживается только с помощью REST API Центров уведомлений.

Вы также можете использовать метод PATCH с помощью стандартаJSON-Patch для обновления установки.

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

Пример кода для регистрации в центре уведомлений с устройства с помощью регистрации

Эти методы создают или обновляют регистрацию для устройства, на котором они вызываются. Это означает, что для обновления идентификатора или тегов необходимо перезаписать всю регистрацию. Помните, что регистрации являются временными, поэтому вы всегда должны иметь надежное хранилище с текущими тегами, которые требуются конкретному устройству.

// 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");
}

Управление регистрацией с бэкэнда

Для управления регистрациями из серверной части требуется написание дополнительного кода. Приложение с устройства должно предоставить обновленный дескриптор PNS серверной части при каждом запуске приложения (вместе с тегами и шаблонами), а серверная часть должна обновить этот дескриптор в центре уведомлений. На следующем рисунке показан этот дизайн.

Управление регистрацией

Преимущества управления регистрацией из серверной части включают возможность изменять теги на регистрации, даже если соответствующее приложение на устройстве неактивно, и для проверки подлинности клиентского приложения перед добавлением тега в регистрацию.

Пример кода для регистрации в узле уведомлений из серверной части с помощью инсталляции

Клиентское устройство по-прежнему получает свой дескриптор PNS и соответствующие свойства установки, как и раньше, и вызывает настраиваемый API на сервере, который может, например, выполнять регистрацию и авторизовать теги. Сервер может использовать пакет SDK Notification Hub для серверных операций.

Вы также можете использовать метод PATCH с помощью стандартаJSON-Patch для обновления установки.

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

Пример кода для регистрации в центре уведомлений из серверной части с помощью идентификатора регистрации

В серверной части приложения можно выполнять основные операции CRUDS с регистрацией. Рассмотрим пример.

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

Серверная часть должна обрабатывать параллелизм между обновлениями регистрации. Уведомительные центры предлагают оптимистическое управление параллельностью для управления регистрацией. На уровне HTTP это реализуется с использованием ETag для операций управления регистрацией. Эта функция прозрачно используется пакетами SDK Майкрософт, которые вызывают исключение, если обновление отклоняется по причинам параллелизма. Серверная часть приложения отвечает за обработку этих исключений и повторную попытку обновления при необходимости.