Azure Notification Hub和WP8 Intermitant通知

时间:2014-07-18 23:33:39

标签: windows-phone-7 azure windows-phone-8 mpns azure-notificationhub

这是一段相当长的代码,但我无法解决这个问题,虽然我不熟悉使用通知中心,但我看不出任何问题。我正在尝试使用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);
        }
    }

我怀疑问题出在我的手机客户端代码中,就在这里,在WebAPI登录后立即调用SubscribeToService;

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

任何帮助都会受到极大关注,因为我已经被困在这几天了!我知道这里有很多代码要粘贴,但它们都是相关的。 谢谢,

编辑:当用户登录并使用WebAPI进行身份验证时,将调用SubscribeToService()方法。方法在这里;

    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 个答案:

答案 0 :(得分:2)

我已经解决了这个问题。对于天蓝色的通知中心来说,有很多相当糟糕的组织方法,其中只有一个有这个音符在底部;

  

注:

     

当您仍在应用中时,您将不会收到通知。   要在应用处于活动状态时收到Toast通知,您必须   处理ShellToastNotificationReceived事件。

这就是我遇到间歇性结果的原因,因为我认为如果你在应用程序中,你仍然会收到通知。这个小小的音符非常隐蔽。

答案 1 :(得分:0)

在注册/发送消息时是否使用了正确的标记/标记表达式。此外,您在何处从通知中心存储ID。当你更新频道uri时它应该被使用(它将过期)。

我建议从头开始。

参考:http://msdn.microsoft.com/en-us/library/dn530749.aspx