Руководство по Отправка уведомлений определенным пользователям с помощью службы "Центры уведомлений Azure"

Обзор

В этом учебнике описано, как использовать Центры уведомлений Azure для отправки push-уведомлений пользователю определенного приложения на конкретном устройстве. Для проверки подлинности клиентов используется серверная часть веб-API ASP.NET. Когда серверная часть проверяет подлинность пользователя клиентского приложения, к регистрации уведомления автоматически добавляется тег. Серверная часть использует этот тег для отправки уведомлений определенному пользователю.

Примечание

Полный код для этого руководства можно найти на GitHub.

При работе с этим руководством вы выполните следующие задачи:

  • Создание проекта веб-API
  • Аутентификация клиентов в серверной части веб-API.
  • Регистрация для получения уведомлений с помощью серверной части веб-API.
  • Отправка уведомлений из серверной части веб-API.
  • Публикация новой серверной части веб-API.
  • Обновите код для клиентского проекта
  • Тестирование приложения

Предварительные требования

В этом руководстве используется центр уведомлений и проект Visual Studio, который вы создали при работе с руководством по отправке уведомлений в приложения универсальной платформы Windows с использованием Центров уведомлений Azure. Выполните инструкции в том руководстве, прежде чем приступать к текущему.

Примечание

Если вы используете мобильные приложения в службе приложений Azure в качестве внутренней службы, то перейдите к версии этого учебника для мобильных приложений.

Создание проекта веб-API

В этой статье описывается создание серверной части веб-API ASP.NET. Этот процесс состоит из трех главных задач.

  • Аутентификация клиентов. Вы добавите обработчик сообщений для аутентификации клиентских запросов и связывания пользователя с запросом.
  • Регистрация для получения уведомлений с помощью серверной части веб-API. Вы добавите контроллер для обработки новых регистраций клиентских устройств для получения уведомлений. Имя пользователя, прошедшего аутентификацию, автоматически добавляется в регистрацию как тег.
  • Отправка уведомлений клиентам. Вы также добавите контроллер, который позволит активировать безопасную отправку push-уведомлений устройствам и клиентам, связанным с тегом.

Чтобы создать серверную часть веб-API ASP.NET Core 6.0, сделайте следующее:

Чтобы проверить, запустите Visual Studio. Откройте меню Средства и выберите пункт Расширения и обновления. Найдите диспетчер пакетов NuGet в своей версии Visual Studio и убедитесь, что у вас установлена последняя версия. Если вы используете не последнюю версию, удалите ее, а затем переустановите диспетчер пакетов NuGet.

Снимок экрана: диалоговое окно

Примечание

Убедитесь, что вы установили пакет SDK для Azure для Visual Studio, используемый для развертывания веб-сайта.

  1. Запустите Visual Studio или Visual Studio Express.

  2. Щелкните Обозреватель серверов и войдите в свою учетную запись Azure. Чтобы создать ресурсы веб-сайта в своей учетной записи, вы должны войти.

  3. В Visual Studio в меню Файл выберите пункты Создать>Проект.

  4. В поле поиска введите Веб-API.

  5. Выберите шаблон проекта Веб-API ASP.NET Core и нажмите кнопку Далее.

  6. В диалоговом окне Настроить новый проект присвойте проекту имя AppBackend и нажмите кнопку Далее.

  7. В диалоговом окне Дополнительные сведения выполните следующие действия.

    • Убедитесь, что для параметра Платформа выбрано значение .NET 6.0 (долгосрочная поддержка).
    • Убедитесь, что флажок Use controllers (uncheck to use minimal APIs) (Использовать контроллеры (снимите этот флажок для использования минимальных API)) установлен.
    • Снимите флажок Включить поддержку OpenAPI.
    • Нажмите кнопку создания.

Удаление файлов шаблонов WeatherForecast

  1. Удалите файлы примеров WeatherForecast.cs и Controllers/WeatherForecastController.cs из нового проекта AppBackend.
  2. Откройте файл Properties\launchSettings.json.
  3. Измените свойства launchUrl с weatherforcast на appbackend.

В окне Настройка веб-приложения Microsoft Azure выберите подписку, а затем в списке План службы приложений выполните одно из следующих действий:

  • Выберите план службы приложений Azure, который вы уже создали.
  • Выберите Создать план служб приложений, а затем создайте его.

База данных для этого руководства не требуется. Выбрав план служб приложений, нажмите кнопку ОК, чтобы создать проект.

Диалоговое окно

Если вы не видите эту страницу для настройки плана службы приложений, продолжайте выполнять руководство. Его можно настроить позднее при публикации приложения.

Аутентификация клиентов в серверной части веб-API.

В этом разделе вы создадите класс обработчика сообщений с именем AuthenticationTestHandler для новой серверной части. Этот класс является производным от DelegatingHandler. Он добавляется в качестве обработчика сообщений, чтобы обрабатывать все запросы, поступающие в серверную часть.

  1. В обозревателе решений щелкните правой кнопкой мыши проект AppBackend, выберите Добавить, а затем щелкните Класс.

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

  3. В AuthenticationTestHandler.cs добавьте следующие операторы using :

    using System.Net.Http;
    using System.Threading;
    using System.Security.Principal;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
  4. В классе AuthenticationTestHandler.cs замените определение AuthenticationTestHandler следующим кодом:

    Обработчик авторизует запрос, если выполнены все три следующих условия:

    • Запрос включен в заголовок авторизации.
    • Запрос использует обычную проверку подлинности.
    • Строка имени пользователя и строка пароля являются одной стройкой.

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

    Если сообщение запроса аутентифицируется и авторизуется AuthenticationTestHandler, пользователь обычной проверки подлинности подключается к текущему запросу в HttpContext. Позднее информацию о пользователе в HttpContext будет использовать другой контроллер (RegisterController), чтобы добавить тег в запрос на регистрацию для получения уведомлений.

    public class AuthenticationTestHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var authorizationHeader = request.Headers.GetValues("Authorization").First();
    
            if (authorizationHeader != null && authorizationHeader
                .StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
            {
                string authorizationUserAndPwdBase64 =
                    authorizationHeader.Substring("Basic ".Length);
                string authorizationUserAndPwd = Encoding.Default
                    .GetString(Convert.FromBase64String(authorizationUserAndPwdBase64));
                string user = authorizationUserAndPwd.Split(':')[0];
                string password = authorizationUserAndPwd.Split(':')[1];
    
                if (VerifyUserAndPwd(user, password))
                {
                    // Attach the new principal object to the current HttpContext object
                    HttpContext.Current.User =
                        new GenericPrincipal(new GenericIdentity(user), new string[0]);
                    System.Threading.Thread.CurrentPrincipal =
                        System.Web.HttpContext.Current.User;
                }
                else return Unauthorized();
            }
            else return Unauthorized();
    
            return base.SendAsync(request, cancellationToken);
        }
    
        private bool VerifyUserAndPwd(string user, string password)
        {
            // This is not a real authentication scheme.
            return user == password;
        }
    
        private Task<HttpResponseMessage> Unauthorized()
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(response);
            return tsc.Task;
        }
    }
    

    Примечание

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

  5. Чтобы зарегистрировать обработчик событий, добавьте в конец метода Register в файле Program.cs следующий код:

    config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Сохраните изменения.

Регистрация для получения уведомлений с помощью серверной части веб-API.

В этом разделе вы добавите новый контроллер в серверную часть веб-API, которая будет обрабатывать запросы на регистрацию пользователя и устройства для получения уведомлений с помощью клиентской библиотеки центров уведомлений. Контроллер будет добавлять тег пользователя для пользователя, который прошел аутентификацию и подключен к HttpContext с помощью AuthenticationTestHandler. Тег имеет формат строки: "username:<actual username>".

  1. В обозревателе решений щелкните правой кнопкой мыши проект AppBackend и выберите пункт Управление пакетами NuGet.

  2. На панели слева выберите В сети, затем в поле поиска введите Microsoft.Azure.NotificationHubs.

  3. В списке результатов выберите Центры уведомлений Microsoft Azure, а затем нажмите кнопку Установить. Завершите установку и закройте окно диспетчера пакетов NuGet.

    Это действие добавляет ссылку на пакет SDK для Центров уведомлений Azure с помощью пакета NuGet Microsoft.Azure.Notification Hubs.

  4. Создайте файл класса, представляющий подключение к концентратору уведомлений, который используется для отправки уведомлений. В обозревателе решений щелкните правой кнопкой мыши папку Модели, выберите Добавить, а затем щелкните Класс. Назовите новый класс Notifications.cs и нажмите кнопку Добавить, чтобы создать класс.

    Окно добавления нового элемента

  5. В Notifications.cs добавьте следующий оператор using в начало файла:

    using Microsoft.Azure.NotificationHubs;
    
  6. Замените определение класса Notifications следующим кодом и замените два заполнителя строкой подключения (с полным доступом) для своего концентратора уведомлений и именем концентратора (доступно на портале Azure):

    public class Notifications
    {
        public static Notifications Instance = new Notifications();
    
        public NotificationHubClient Hub { get; set; }
    
        private Notifications() {
            Hub = NotificationHubClient.CreateClientFromConnectionString("<your hub's DefaultFullSharedAccessSignature>",
                                                                            "<hub name>");
        }
    }
    

    Важно!

    Прежде чем продолжить, введите имя и DefaultFullSharedAccessSignature вашего концентратора.

  7. Теперь создайте новый контроллер с именем RegisterController. В обозревателе решений щелкните правой кнопкой мыши папку Контроллеры, выберите Добавить, а затем щелкните Контроллер.

  8. Выберите Контроллер API — пустой, а затем нажмите кнопку Добавить.

  9. В поле Имя контроллера введите имя нового класса RegisterController, а затем нажмите кнопку Добавить.

    Окно Добавление контроллера.

  10. В RegiterController.cs добавьте следующие операторы using :

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Добавьте в определение класса RegisterController следующий код: В этом коде вы добавите тег для пользователя, который подключен к HttpContext. Пользователь прошел аутентификацию и подключен к HttpContext с помощью добавленного фильтра сообщений AuthenticationTestHandler. Вы можете также добавить дополнительные проверки, чтобы убедиться, что у пользователя есть право регистрации запрошенных тегов.

    private NotificationHubClient hub;
    
    public RegisterController()
    {
        hub = Notifications.Instance.Hub;
    }
    
    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(string handle = null)
    {
        string newRegistrationId = null;
    
        // make sure there are no existing registrations for this push handle (used for iOS and Android)
        if (handle != null)
        {
            var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100);
    
            foreach (RegistrationDescription registration in registrations)
            {
                if (newRegistrationId == null)
                {
                    newRegistrationId = registration.RegistrationId;
                }
                else
                {
                    await hub.DeleteRegistrationAsync(registration);
                }
            }
        }
    
        if (newRegistrationId == null) 
            newRegistrationId = await hub.CreateRegistrationIdAsync();
    
        return newRegistrationId;
    }
    
    // PUT api/register/5
    // This creates or updates a registration (with provided channelURI) at the specified id
    public async Task<HttpResponseMessage> Put(string id, DeviceRegistration deviceUpdate)
    {
        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 "fcm":
                registration = new FcmRegistrationDescription(deviceUpdate.Handle);
                break;
            default:
                throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    
        registration.RegistrationId = id;
        var username = HttpContext.Current.User.Identity.Name;
    
        // add check if user is allowed to add these tags
        registration.Tags = new HashSet<string>(deviceUpdate.Tags);
        registration.Tags.Add("username:" + username);
    
        try
        {
            await hub.CreateOrUpdateRegistrationAsync(registration);
        }
        catch (MessagingException e)
        {
            ReturnGoneIfHubResponseIsGone(e);
        }
    
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    // DELETE api/register/5
    public async Task<HttpResponseMessage> Delete(string id)
    {
        await hub.DeleteRegistrationAsync(id);
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    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());
        }
    }
    
  12. Сохраните изменения.

Отправка уведомлений из серверной части веб-API.

В этом разделе вы добавите новый контроллер, который позволяет клиентским устройствам отправлять уведомления. Уведомление основано на теге имени пользователя, который использует библиотеку .NET центров уведомлений Azure в серверной части веб-API ASP.NET.

  1. Создайте еще один контроллер с именем NotificationsController так же, как вы создали RegisterController в предыдущем разделе.

  2. В NotificationsController.cs добавьте следующие операторы using :

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. Добавьте следующий метод в класс NotificationsController:

    Этот код отправляет тип уведомлений, основанный на параметре pns системы отправки уведомлений платформы (PNS). Значение to_tag используется для задания тега имени пользователя в сообщении. Этот тег должен соответствовать тегу имени пользователя активной регистрации центра уведомлений. Сообщение уведомления извлекается из текста запроса POST и форматируется для целевого PNS.

    Поддержка форматов уведомлений зависит от того, какую систему PNS используют поддерживаемые устройства. Например, на устройствах Windows можно использовать всплывающие уведомления с помощью WNS, которые не поддерживает другая система PNS. В этом случае серверная часть решения конвертирует уведомление в формат, соответствующий PNS устройств, которые вы планируете поддерживать. Затем используйте соответствующий API отправки для класса NotificationHubClient.

    public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag)
    {
        var user = HttpContext.Current.User.Identity.Name;
        string[] userTag = new string[2];
        userTag[0] = "username:" + to_tag;
        userTag[1] = "from:" + user;
    
        Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
        HttpStatusCode ret = HttpStatusCode.InternalServerError;
    
        switch (pns.ToLower())
        {
            case "wns":
                // Windows 8.1 / Windows Phone 8.1
                var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">" + 
                            "From " + user + ": " + message + "</text></binding></visual></toast>";
                outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag);
                break;
            case "apns":
                // iOS
                var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag);
                break;
            case "fcm":
                // Android
                var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendFcmNativeNotificationAsync(notif, userTag);
                break;
        }
    
        if (outcome != null)
        {
            if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) ||
                (outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown)))
            {
                ret = HttpStatusCode.OK;
            }
        }
    
        return Request.CreateResponse(ret);
    }
    
  4. Нажмите клавишу F5, чтобы запустить приложение и убедиться, что все правильно работает. Приложение откроется в веб-браузере и отобразится на домашней странице ASP.NET.

Публикация новой серверной части веб-API.

Теперь разверните приложение на веб-сайте Azure, чтобы сделать его доступным для всех устройств.

  1. Щелкните правой кнопкой мыши проект AppBackend и нажмите кнопку Опубликовать.

  2. Выберите службу приложений Microsoft Azure, в которой вы хотите опубликовать приложение, и нажмите кнопку \*\*Опубликовать. Откроется окно создания службы приложений. В этом окне можно создать все необходимые ресурсы Azure для запуска веб-приложения ASP.NET в Azure.

    Плитка службы приложений Microsoft Azure

  3. В окне Создание службы приложений выберите свою учетную запись Azure. Выберите Изменить тип>Веб-приложение. Не изменяйте стандартное имя веб-приложения. Выберите подписку, группу ресурсов и план службы приложений.

  4. Нажмите кнопку создания.

  5. Запишите свойство URL-адрес сайта в разделе Сводка. Это URL-адрес конечной точки внутренней части.

  6. Нажмите Публиковать.

Когда мастер завершит работу, веб-приложение ASP.NET будет опубликовано в Azure и откроется в браузере по умолчанию. Приложение также будет отображаться в службах приложений Azure.

В URL-адресе используется имя веб-приложения, указанное ранее, в формате http://<имя_приложения>.azurewebsites.net.

Обновление кода клиента UWP

В этом разделе описано, как обновить код в проекте, который вы завершили при работе с руководством по отправке уведомлений в приложения универсальной платформы Windows с использованием Центров уведомлений Azure. Проект уже должен быть связан с Магазином Windows. Он также должен использовать Центр уведомлений. В этом разделе вы добавляете код для вызова нового серверного веб-API и используете его для регистрации и отправки уведомлений.

  1. Откройте решение Visual Studio, созданное при работе с руководством по отправке уведомлений в приложения универсальной платформы Windows с использованием Центров уведомлений Azure.

  2. В обозревателе решений щелкните правой кнопкой мыши проект универсальной платформы Windows (UWP) и выберите Управление пакетами NuGet.

  3. В области слева выберите Обзор.

  4. В текстовом поле Поиск введите Клиент HTTP.

  5. В списке результатов щелкните System.Net.Http и выберите Установить. Выполните установку.

  6. Вернитесь к полю NuGet Поиск и введите Json.net. Установите пакет Newtonsoft.json, а затем закройте окно диспетчера пакетов NuGet.

  7. В обозревателе решений в проекте WindowsApp дважды щелкните MainPage.xaml, чтобы открыть его в редакторе Visual Studio.

  8. В файле MainPage.xaml замените раздел <Grid> следующим кодом: Этот код добавляет текстовое поле имени пользователя и пароля, которые будут использоваться для проверки подлинности пользователя. Он также добавляет текстовые поля для сообщения уведомления и тег имени пользователя, который должен получать уведомления:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    
        <TextBlock Grid.Row="0" Text="Notify Users" HorizontalAlignment="Center" FontSize="48"/>
    
        <StackPanel Grid.Row="1" VerticalAlignment="Center">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.ColumnSpan="3" Text="Username" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="UsernameTextBox" Grid.Row="1" Grid.ColumnSpan="3" Margin="20,0,20,0"/>
                <TextBlock Grid.Row="2" Grid.ColumnSpan="3" Text="Password" FontSize="24" Margin="20,0,20,0" />
                <PasswordBox Name="PasswordTextBox" Grid.Row="3" Grid.ColumnSpan="3" Margin="20,0,20,0"/>
    
                <Button Grid.Row="4" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center"
                            Content="1. Login and register" Click="LoginAndRegisterClick" Margin="0,0,0,20"/>
    
                <ToggleButton Name="toggleWNS" Grid.Row="5" Grid.Column="0" HorizontalAlignment="Right" Content="WNS" IsChecked="True" />
                <ToggleButton Name="toggleFCM" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Center" Content="FCM" />
                <ToggleButton Name="toggleAPNS" Grid.Row="5" Grid.Column="2" HorizontalAlignment="Left" Content="APNS" />
    
                <TextBlock Grid.Row="6" Grid.ColumnSpan="3" Text="Username Tag To Send To" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="ToUserTagTextBox" Grid.Row="7" Grid.ColumnSpan="3" Margin="20,0,20,0" TextWrapping="Wrap" />
                <TextBlock Grid.Row="8" Grid.ColumnSpan="3" Text="Enter Notification Message" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="NotificationMessageTextBox" Grid.Row="9" Grid.ColumnSpan="3" Margin="20,0,20,0" TextWrapping="Wrap" />
                <Button Grid.Row="10" Grid.ColumnSpan="3" HorizontalAlignment="Center" Content="2. Send push" Click="PushClick" Name="SendPushButton" />
            </Grid>
        </StackPanel>
    </Grid>
    
  9. В обозревателе решений откройте файл MainPage.xaml.cs для проектов (Windows 8.1) и (Windows Phone 8.1) . В верхнюю часть каждого из файлов добавьте такие using операторы:

    using System.Net.Http;
    using Windows.Storage;
    using System.Net.Http.Headers;
    using Windows.Networking.PushNotifications;
    using Windows.UI.Popups;
    using System.Threading.Tasks;
    
  10. В файле MainPage.xaml.cs для проекта WindowsApp добавьте в класс MainPage следующий элемент. Обязательно замените <Enter Your Backend Endpoint> фактической конечной точкой серверной части, полученной ранее. Например, http://mybackend.azurewebsites.net.

    private static string BACKEND_ENDPOINT = "<Enter Your Backend Endpoint>";
    
  11. В файле MainPage.xaml.cs для проектов (Windows 8.1) и (Windows Phone 8.1) добавьте в класс MainPage приведенный ниже код.

    Метод PushClick является обработчиком нажатия для кнопки Отправить push-уведомление . Он обеспечивает отправку серверной частью уведомлений на все устройства с тегом имени пользователя, который соответствует параметру to_tag . Сообщение уведомления отправляется в виде JSON-содержимого в теле запроса.

    Метод LoginAndRegisterClick является обработчиком нажатия для кнопки Вход и регистрация. Он сохраняет маркер проверки подлинности (относится к любому маркеру, используемому в данной схеме проверки подлинности) в локальном хранилище, а затем с помощью RegisterClient подписывается на получение уведомлений, используя серверную часть.

    private async void PushClick(object sender, RoutedEventArgs e)
    {
        if (toggleWNS.IsChecked.Value)
        {
            await sendPush("wns", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
        }
        if (toggleFCM.IsChecked.Value)
        {
            await sendPush("fcm", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
        }
        if (toggleAPNS.IsChecked.Value)
        {
            await sendPush("apns", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
    
        }
    }
    
    private async Task sendPush(string pns, string userTag, string message)
    {
        var POST_URL = BACKEND_ENDPOINT + "/api/notifications?pns=" +
            pns + "&to_tag=" + userTag;
    
        using (var httpClient = new HttpClient())
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]);
    
            try
            {
                await httpClient.PostAsync(POST_URL, new StringContent("\"" + message + "\"",
                    System.Text.Encoding.UTF8, "application/json"));
            }
            catch (Exception ex)
            {
                MessageDialog alert = new MessageDialog(ex.Message, "Failed to send " + pns + " message");
                alert.ShowAsync();
            }
        }
    }
    
    private async void LoginAndRegisterClick(object sender, RoutedEventArgs e)
    {
        SetAuthenticationTokenInLocalStorage();
    
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
        // The "username:<user name>" tag gets automatically added by the message handler in the backend.
        // The tag passed here can be whatever other tags you may want to use.
        try
        {
            // The device handle used is different depending on the device and PNS.
            // Windows devices use the channel uri as the PNS handle.
            await new RegisterClient(BACKEND_ENDPOINT).RegisterAsync(channel.Uri, new string[] { "myTag" });
    
            var dialog = new MessageDialog("Registered as: " + UsernameTextBox.Text);
            dialog.Commands.Add(new UICommand("OK"));
            await dialog.ShowAsync();
            SendPushButton.IsEnabled = true;
        }
        catch (Exception ex)
        {
            MessageDialog alert = new MessageDialog(ex.Message, "Failed to register with RegisterClient");
            alert.ShowAsync();
        }
    }
    
    private void SetAuthenticationTokenInLocalStorage()
    {
        string username = UsernameTextBox.Text;
        string password = PasswordTextBox.Password;
    
        var token = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
        ApplicationData.Current.LocalSettings.Values["AuthenticationToken"] = token;
    }
    
  12. В обработчике событий InitNotificationsAsync() откройте файл App.xaml.cs и найдите вызов OnLaunched(): Закомментируйте или удалите вызов InitNotificationsAsync(). Обработчик кнопки инициализирует регистрации уведомлений.

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        //InitNotificationsAsync();
    
  13. Щелкните правой кнопкой мыши проект WindowsApp, а затем выберите пункты Добавить и Класс. Присвойте классу имя RegisterClient.cs, а затем нажмите кнопку ОК, чтобы создать класс.

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

  14. Добавьте в начало файла RegisterClient.cs следующие операторы using :

    using Windows.Storage;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using Newtonsoft.Json;
    using System.Threading.Tasks;
    using System.Linq;
    
  15. Добавьте в определение класса RegisterClient следующий код:

    private string POST_URL;
    
    private class DeviceRegistration
    {
        public string Platform { get; set; }
        public string Handle { get; set; }
        public string[] Tags { get; set; }
    }
    
    public RegisterClient(string backendEndpoint)
    {
        POST_URL = backendEndpoint + "/api/register";
    }
    
    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 && statusCode != HttpStatusCode.OK)
        {
            // log or throw
            throw new System.Net.WebException(statusCode.ToString());
        }
    }
    
    private async Task<HttpStatusCode> UpdateRegistrationAsync(string regId, DeviceRegistration deviceRegistration)
    {
        using (var httpClient = new HttpClient())
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string) settings["AuthenticationToken"]);
    
            var putUri = POST_URL + "/" + regId;
    
            string json = JsonConvert.SerializeObject(deviceRegistration);
                            var response = await httpClient.PutAsync(putUri, new StringContent(json, Encoding.UTF8, "application/json"));
            return response.StatusCode;
        }
    }
    
    private async Task<string> RetrieveRegistrationIdOrRequestNewOneAsync()
    {
        var settings = ApplicationData.Current.LocalSettings.Values;
        if (!settings.ContainsKey("__NHRegistrationId"))
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]);
    
                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 System.Net.WebException(response.StatusCode.ToString());
                }
            }
        }
        return (string)settings["__NHRegistrationId"];
    
    }
    
  16. Сохраните изменения.

Тестирование приложения

  1. Запустите приложение в обоих Windows.

  2. Введите Имя пользователя и Пароль, как показано ниже. Они должны отличаться от имени пользователя и пароля, вводимых в Windows Phone.

  3. Щелкните Вход и регистрация и убедитесь, что в диалоговом окне отображается подтверждение выполнения входа. Таким образом, будет активирована кнопка Отправить push-уведомление.

    Снимок экрана: приложение для Центров уведомлений, в котором отображаются введенные имя пользователя и пароль.

  4. Затем в поле Тег имени получателя введите зарегистрированное имя пользователя. Введите сообщение уведомления и нажмите кнопку Отправить push-уведомление.

  5. Сообщения уведомления могут получать только устройства с зарегистрированным соответствующим тегом имени получателя.

    Снимок экрана: приложение для Центров уведомлений, в котором отображается отправленное сообщение.

Дальнейшие действия

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