1

这是一段相当长的代码,但我对此一无所知,也看不到任何问题,尽管我是使用通知中心的新手。我正在尝试使用 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;
            }
    // ...
        }
    }
4

2 回答 2

2

我已经解决了这个问题。天蓝色通知中心有大量组织不善的操作指南,其中只有一个在底部有此注释;

笔记:

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

这就是我遇到间歇性结果的原因,因为我认为如果您在应用程序中,您仍然会收到通知。这个小纸条被很好地隐藏了。

于 2014-07-22T15:18:54.173 回答
0

您在注册/发送消息时是否使用了正确的标签/标签表达式。此外,您在哪里将 id 从通知中心存储回来。更新频道 uri 时应该使用它(它将过期)。

我建议从头开始。

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

于 2014-07-22T13:30:22.993 回答