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


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

Обзор

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

Примечание.

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

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

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

Предпосылки

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

Примечание.

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

Создание проекта WebAPI

В следующих разделах рассматривается создание серверной части ASP.NET WebAPI. Этот процесс имеет три основных цели:

  • Проверка подлинности клиентов: вы добавляете обработчик сообщений для проверки подлинности клиентских запросов и связываете пользователя с запросом.
  • Зарегистрируйтесь для уведомлений с помощью серверной части WebAPI: вы добавляете контроллер для обработки новых регистраций для клиентского устройства для получения уведомлений. Имя пользователя, прошедшее проверку подлинности, автоматически добавляется в регистрацию в качестве тега.
  • Отправка уведомлений клиентам: вы добавляете контроллер, чтобы предоставить пользователям возможность активировать безопасную отправку на устройства и клиенты, связанные с тегом.

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

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

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

Примечание.

Убедитесь, что у вас установлен Azure SDK для 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. Откройте файл Свойства\launchSettings.json.
  3. Измените свойства launchUrl с weatherforcast на appbackend.

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

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

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

Окно

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

Проверка подлинности клиентов в серверной части WebAPI

В этом разделе описано, как создать класс обработчика сообщений с именем 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. Сохраните ваши изменения.

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

В этом разделе вы добавите новый контроллер в серверную часть WebAPI для обработки запросов на регистрацию пользователя и устройства для уведомлений с помощью клиентской библиотеки для центров уведомлений. Контроллер добавляет тег пользователю, который был аутентифицирован и прикреплен к 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. В RegisterController.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. Сохраните ваши изменения.

Отправка уведомлений из серверной части WebAPI

В этом разделе вы добавите новый контроллер, предоставляющий способ отправки уведомления клиентским устройствам. Уведомление основано на теге имени пользователя, использующем библиотеку .NET Центров уведомлений Azure в серверной части webAPI 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.

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

Затем вы развернете приложение на веб-сайте 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://< app_name.azurewebsites.net>.

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

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

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

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

  3. В левой части нажмите кнопку "Обзор".

  4. В поле поиска введите Http Client.

  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> на актуальный URL конечной точки вашего backend-сервера, полученной ранее. Например, http://mybackend.azurewebsites.net.

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

    Метод PushClick — это обработчик нажатия кнопки "Отправить". Он вызывает серверную часть, чтобы активировать уведомление для всех устройств с тегом имени пользователя, который соответствует параметру 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. Откройте App.xaml.cs и найдите вызов InitNotificationsAsync() в обработчике OnLaunched() событий. Закомментируйте или удалите вызов InitNotificationsAsync(). Обработчик кнопки инициализирует регистрации уведомлений:

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

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

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

    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-уведомления определенным пользователям с тегами, связанными с их регистрацией. Чтобы узнать, как отправлять уведомления на основе расположения, перейдите к следующему руководству: