Центр уведомлений Azure и промежуточные уведомления WP8

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

У меня проблема в том, что иногда на устройство отправляется уведомление, а иногда нет. В основном это не так, но иногда, когда я перебираю код на сервере, я получаю уведомление на эмуляторе. Однажды, когда я развернул приложение на своем телефоне, на эмуляторе пришло уведомление! Я не могу обнаружить образец.

Мой класс Controller выглядит следующим образом;

    private NotificationHelper hub;

    public RegisterController()
    {
        hub = NotificationHelper.Instance;
    }
    public async Task<RegistrationDescription> Post([FromBody]JObject registrationCall)
    {        
        var obj = await hub.Post(registrationCall);
        return obj;
    }

И вспомогательный класс (который используется в другом месте, поэтому не находится непосредственно в контроллере) выглядит следующим образом;

    public static NotificationHelper Instance = new NotificationHelper();

    public NotificationHubClient Hub { get; set; }

    // Create the client in the constructor.
    public NotificationHelper()
    {
        var cn = "<my-cn>";
        Hub = NotificationHubClient.CreateClientFromConnectionString(cn, "<my-hub>");
    }

    public async Task<RegistrationDescription> Post([FromBody] JObject registrationCall)
    {            
        // Get the registration info that we need from the request. 
        var platform = registrationCall["platform"].ToString();
        var installationId = registrationCall["instId"].ToString();
        var channelUri = registrationCall["channelUri"] != null
            ? registrationCall["channelUri"].ToString()
            : null;
        var deviceToken = registrationCall["deviceToken"] != null
            ? registrationCall["deviceToken"].ToString()
            : null;
        var userName = HttpContext.Current.User.Identity.Name;

        // Get registrations for the current installation ID.
        var regsForInstId = await Hub.GetRegistrationsByTagAsync(installationId, 100);

        var updated = false;
        var firstRegistration = true;
        RegistrationDescription registration = null;

        // Check for existing registrations.
        foreach (var registrationDescription in regsForInstId)
        {
            if (firstRegistration)
            {
                // Update the tags.
                registrationDescription.Tags = new HashSet<string>() {installationId, userName};

                // We need to handle each platform separately.
                switch (platform)
                {
                    case "windows":
                        var winReg = registrationDescription as MpnsRegistrationDescription;
                        winReg.ChannelUri = new Uri(channelUri);
                        registration = await Hub.UpdateRegistrationAsync(winReg);
                        break;
                    case "ios":
                        var iosReg = registrationDescription as AppleRegistrationDescription;
                        iosReg.DeviceToken = deviceToken;
                        registration = await Hub.UpdateRegistrationAsync(iosReg);
                        break;
                }
                updated = true;
                firstRegistration = false;
            }
            else
            {
                // We shouldn't have any extra registrations; delete if we do.
                await Hub.DeleteRegistrationAsync(registrationDescription);
            }
        }

        // Create a new registration.
        if (!updated)
        {
            switch (platform)
            {
                case "windows":
                    registration = await Hub.CreateMpnsNativeRegistrationAsync(channelUri,
                        new string[] {installationId, userName});
                    break;
                case "ios":
                    registration = await Hub.CreateAppleNativeRegistrationAsync(deviceToken,
                        new string[] {installationId, userName});
                    break;
            }
        }

        // Send out a test notification.
        await SendNotification(string.Format("Test notification for {0}", userName), userName);

        return registration;

И наконец, мой метод SendNotification здесь;

    internal async Task SendNotification(string notificationText, string tag)
    {
        try
        {
            var toast = PrepareToastPayload("<my-hub>", notificationText);
            // Send a notification to the logged-in user on both platforms.
            await NotificationHelper.Instance.Hub.SendMpnsNativeNotificationAsync(toast, tag);      
            //await hubClient.SendAppleNativeNotificationAsync(alert, tag);
        }
        catch (ArgumentException ex)
        {
            // This is expected when an APNS registration doesn't exist.
            Console.WriteLine(ex.Message);
        }
    }

Я подозреваю, что проблема в коде моего телефона клиента, который находится здесь, и SubscribeToService вызывается сразу после входа в WebAPI;

    public void SubscribeToService()
    {
        _channel = HttpNotificationChannel.Find("mychannel");
        if (_channel == null)
        {
            _channel = new HttpNotificationChannel("mychannel");
            _channel.Open();
            _channel.BindToShellToast();
        }

        _channel.ChannelUriUpdated += async (o, args) =>
                                            {              
                                                var hub = new NotificationHub("<my-hub>", "<my-cn>");
                                                await hub.RegisterNativeAsync(args.ChannelUri.ToString());
                                                await RegisterForMessageNotificationsAsync();

                                            };

    }

    public async Task RegisterForMessageNotificationsAsync()
    {
        using (var client = GetNewHttpClient(true))
        {
            // Get the info that we need to request registration.
            var installationId = LocalStorageManager.GetInstallationId(); // a new Guid

            var registration = new Dictionary<string, string>()
                               {
                                   {"platform", "windows"},
                                   {"instId", installationId},
                                   {"channelUri", _channel.ChannelUri.ToString()}
                               };

            var request = new HttpRequestMessage(HttpMethod.Post, new Uri(ApiUrl + "api/Register/RegisterForNotifications"));

            request.Content = new StringContent(JsonConvert.SerializeObject(registration), Encoding.UTF8, "application/json");

            string message;

            try
            {
                HttpResponseMessage response = await client.SendAsync(request);
                message = await response.Content.ReadAsStringAsync();
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }
            _registrationId = message;
        }
}

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

РЕДАКТИРОВАТЬ: метод SubscribeToService() вызывается, когда пользователь входит в систему и аутентифицируется с помощью WebAPI. Метод здесь;

    public async Task<User> SendSubmitLogonAsync(LogonObject lo)
    {
        _logonObject = lo;
        using (var client = GetNewHttpClient(false))
        {
        var logonString = String.Format("grant_type=password&username={0}&password={1}", lo.username, lo.password);
            var sc = new StringContent(logonString, Encoding.UTF8);

            var response = await client.PostAsync("Token", sc);
            if (response.IsSuccessStatusCode)
            {
                _logonResponse = await response.Content.ReadAsAsync<TokenResponseModel>();
                var userInfo = await GetUserInfoAsync();                

                if (_channel == null)
                    SubscribeToService();
                else
                    await RegisterForMessageNotificationsAsync();                 

                return userInfo;
            }
    // ...
        }
    }

2 ответа

Решение

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

НОТА:

Вы не будете получать уведомления, когда вы еще в приложении. Чтобы получать всплывающее уведомление, когда приложение активно, вы должны обработать событие ShellToastNotificationReceived.

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

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

Я бы предложил начать с нуля.

Ссылка: http://msdn.microsoft.com/en-us/library/dn530749.aspx

Другие вопросы по тегам