Azure通知集线器推送通知失败或提供无效或不完整的数据

时间:2017-04-02 05:12:07

标签: php azure xamarin.android azure-notificationhub

我使用以下php代码使用Azure Notification Hub向Android应用程序发送推送通知。

$hub = new NotificationHub("Endpoint=sb://ServiceName.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SharedAccessKey", "ServiceNameNotification");

        $message = '{"data":{"message":"This is a sample notification","title":"Sample Notification","action":"Test","action_id":"60"}}';
        $notification = new AzureNotification("gcm", $message);
        $hub->sendNotification($notification, null);

但遗憾的是,大部分时间通知都没有送达,尽管我收到201作为回复。无论何时交付,结果都是不可预测的,有时旧通知的内容最终会显示出来。

以下代码用于显示Android应用中的通知(Xamarin.Android):

using System;
using Android.App;
using Android.Content;
using Gcm.Client;
using Microsoft.WindowsAzure.MobileServices;
using Newtonsoft.Json.Linq;
using ServiceName.Helpers;

[assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
//GET_ACCOUNTS is needed only for Android versions 4.0.3 and below
[assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
namespace ServiceName.Droid
{
    [BroadcastReceiver(Permission = Gcm.Client.Constants.PERMISSION_GCM_INTENTS)]
    [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_MESSAGE },
        Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK },
        Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_LIBRARY_RETRY },
        Categories = new string[] { "@PACKAGE_NAME@" })]
    public class ServiceNameBroadcastReceiver : GcmBroadcastReceiverBase<PushHandlerService>
    {
        public static string[] senderIDs = new string[] { Constants.SenderID };

        public const string TAG = "MyBroadcastReceiver-GCM";
    }
    // The ServiceAttribute must be applied to the class.
    [Service]
    public class PushHandlerService : GcmServiceBase
    {

        public static string RegistrationID { get; private set; }

        public PushHandlerService() : base(ServiceNameBroadcastReceiver.senderIDs) { }
        protected override void OnMessage(Context context, Intent intent)
        {
            string message = string.Empty;
            string title = string.Empty;
            string action = string.Empty;
            string action_id = string.Empty;
            if (intent.Extras.ContainsKey("title"))
            {
                title = intent.Extras.Get("title").ToString();
            }
            if (intent.Extras.ContainsKey("message"))
            {
                message = intent.Extras.Get("message").ToString();
            }
            if (intent.Extras.ContainsKey("action"))
            {
                action = intent.Extras.Get("action").ToString();
            }
            if (intent.Extras.ContainsKey("action_id"))
            {
                action_id = intent.Extras.Get("action_id").ToString();
            }

            // Extract the push notification message from the intent.
            if (!string.IsNullOrWhiteSpace(message) || !string.IsNullOrWhiteSpace(title))
            {
                // Create a notification manager to send the notification.
                var notificationManager =
                    GetSystemService(Context.NotificationService) as NotificationManager;

                // Create a new intent to show the notification in the UI. 
                PendingIntent contentIntent =
                    PendingIntent.GetActivity(context, 0,
                                              new Intent(this, typeof(MainActivity)), 0);

                // Create the notification using the builder.
                var builder = new Notification.Builder(context);
                builder.SetAutoCancel(false);
                if (!string.IsNullOrWhiteSpace(title))
                {
                    builder.SetContentTitle(title);
                }
                else
                {
                    builder.SetContentTitle("Notification from ServiceName");
                }
                if (!string.IsNullOrWhiteSpace(message))
                {
                    builder.SetContentText(message);
                }
                else
                {
                    builder.SetContentText("Hello ServiceName User");
                }
                builder.SetSmallIcon(Resource.Drawable.ic_stat_icon);
                builder.SetContentIntent(contentIntent);
                var notification = builder.Build();

                // Display the notification in the Notifications Area.
                notificationManager.Notify(1, notification);

            }
        }
        protected override void OnError(Context context, string errorId)
        {
            System.Diagnostics.Debug.WriteLine(
                string.Format("Error occurred in the notification: {0}.", errorId));
        }
        protected override async void OnRegistered(Context context, string registrationId)
        {
            System.Diagnostics.Debug.WriteLine("The device has been registered with GCM.", "Success!");

            // Get the MobileServiceClient from the current activity instance.
            MobileServiceClient client = MainActivity.CurrentActivity.CurrentClient;
            var push = client.GetPush();

            // Define a message body for GCM.
            const string templateBodyGCM = "{\"data\":{\"message\":\"$(messageParam)\", \"title\": \"$(titleParam)\", \"action\":\"$(actionParam)\",\"action_id\":\"$(action_idParam)\"}}";

            // Define the template registration as JSON.
            JObject templates = new JObject();
            templates["genericMessage"] = new JObject
            {
                {"body", templateBodyGCM }
            };

            try
            {
                // Make sure we run the registration on the same thread as the activity, 
                // to avoid threading errors.
                MainActivity.CurrentActivity.RunOnUiThread(
                    // Register the template with Notification Hubs.
                    async () => {

                        try
                        {
                        await push.RegisterAsync(registrationId, templates);

                        System.Diagnostics.Debug.WriteLine(
                    string.Format("Push Installation Id " + push.InstallationId.ToString()));


                var res = await MiscServices.RegisterDevice(Settings.UserID, Settings.AccessToken, push.InstallationId.ToString(), "gcm");
                if ((bool)res.data)
                {
                    System.Diagnostics.Debug.WriteLine("Registered InstallationId in Server");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Cannot register with Server" + " " + res.status.StatusCode);
                }

            }
                        catch (Exception e)
                        {
                        }

                });


            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(
                    string.Format("Error with Azure push registration: {0}", ex.Message));
            }
        }

        protected override void OnUnRegistered(Context context, string registrationId)
        {
            System.Diagnostics.Debug.WriteLine("Unregistered with Azure push registration");
            }
    }

}

即使测试通知有时也无法送达,但大多数测试通知都能正常工作。我们无法确定问题发生的位置,非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

当您成功向Azure NH发送邮件时,获得了201条回复。当您通过通知中心发送通知时,最初它只是排队等待NH进行处理以找出其所有目标,然后最终NH将其发送到PNS。

这意味着当您使用REST API或任何客户端SDK时,成功返回您的发送呼叫只意味着该消息已成功排队使用Notification Hub。

它无法深入了解NH最终将消息发送给PNS时发生的事情。如果您的通知未到达客户端设备,则当NH尝试将消息发送到PNS时,可能会出现错误,例如有效负载大小超过PNS允许的最大值或NH中配置的凭证无效等。

为了深入了解PNS错误,我们引入了一个名为EnableTestSend功能的属性。从门户网站或Visual Studio客户端发送测试消息时,将自动启用此属性,因此您可以查看详细的调试信息。

或者您可以尝试通过RESTful API进行调用以进行故障排除: https://mynamespace.servicebus.windows.net/mynotificationhub/messages?api-version=2013-10&test

有关详细信息,请参阅Azure Notification Hubs - Diagnosis guidelines