1

これはかなり長いコードですが、通知ハブの使用は初めてですが、これでうまくいかず、問題も見られません。Azure の通知ハブを使用して、対象の通知 (ログオンしているユーザー) に登録しようとしています。登録後、テスト通知が送信されます。

私が抱えている問題は、通知がデバイスに送信される場合と送信されない場合があることです。ほとんどの場合そうではありませんが、サーバー上のコードをステップ実行すると、エミュレーターで通知が届くことがあります。アプリを自分の携帯電話にデプロイすると、エミュレーターに通知が届きました! パターンを発見できません。

私のコントローラークラスは次のようになります。

    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;
            }
    // ...
        }
    }
4

2 に答える 2