Skip to content

Apns notification error: 'ConnectionError' System.NullReferenceException #672

Open

Description

@attilabicsko

I'm using PushSharp 4.0.4, installed from NuGet

In the OnNotificationFailed(ApnsNotification, AggregateException) event of the Apns broker, I often get this exception:

PushSharp.Apple.ApnsNotificationException: Apns notification error: 'ConnectionError'
---> System.NullReferenceException: Object reference not set to an instance of an object.

at PushSharp.Apple.ApnsConnection.createBatch(List`1 toSend)
at PushSharp.Apple.ApnsConnection.d__21.MoveNext()

--- End of inner exception stack trace ---
at PushSharp.Apple.ApnsServiceConnection.d__2.MoveNext()

It seems to happen randomly. I'm using PushSharp in a Windows Service, running multiple (>300) brokers in the same time stored in a singleton object's ConcurrentDictionary, if that helps.

Please advise how to troubleshoot this error.

Activity

  1. attilabicsko commented on Apr 1, 2016

    @attilabicsko
    Author

    Beside this, sometimes I get the following exception, also in OnNotificationFailed:

    System.ArgumentException: Source array was not long enough. Check srcIndex and length, and the array's lower bounds.
    at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
    at System.Collections.Generic.Queue1.SetCapacity(Int32 capacity) at System.Collections.Generic.Queue1.Enqueue(T item)
    at PushSharp.Apple.ApnsConnection.Send(CompletableApnsNotification notification)
    at PushSharp.Apple.ApnsServiceConnection.d__2.MoveNext()

    Am I doing something wrong or misunderstanding the concept, or could this happen due to a bug?

  2. iinke commented on Apr 4, 2016

    @iinke

    Same happens for me.
    It reproduces even with 1 broker, just not so often.

    Looks like problem is in ApnsConnection class: notifications queue ( Queue<CompletableApnsNotification> notifications ) isn't thread-safe. I think this queue isn't thread-safe because of timerBatchWait timer: timer's callback executes on a new thread, not the broker thread.
    If you for example place locks around all places where notifications.Enqueue/notifications.Dequeue is called (lock (notificationBatchQueueLock)), error doesn't seem to reproduce anymore. Should ConcurrentQueue be used instead of Queue here?

  3. mohammadjouhari commented on Apr 10, 2016

    @mohammadjouhari

    any update on this. I am getting the same issue right here.

  4. mohammadjouhari commented on Apr 11, 2016

    @mohammadjouhari

    @iinke I have a lock statement around the method that it is queening the device tokens. I am also creating batches and Queue device tokens in a timer. So in each 3 seconds I am queering 100 devices. But I am still getting this connection error.

  5. added a commit that references this issue on Apr 13, 2016
  6. gabrieligbastos commented on Apr 17, 2016

    @gabrieligbastos

    Didnt get it. Is it a bug or am I also doing something wrong?

  7. mohammadjouhari commented on Apr 18, 2016

    @mohammadjouhari

    @gabrieligbastos it is a bug. Why this error is coming ?

  8. gabrieligbastos commented on Apr 18, 2016

    @gabrieligbastos

    I have no clue why? It is just sometimes it just give me back this exception. Seems randomly, Could not find a situation that always happens.

    Before update my NugetPackage to the new version, it was not getting this error.

  9. gabrieligbastos commented on May 3, 2016

    @gabrieligbastos

    Any update to workaround this?

  10. sparity123 commented on May 24, 2016

    @sparity123

    I too have the same issue : Connection Error
    I recently updated pushsharp library to 4.0.10, if i put thread.sleep(1000) in for loop notifications will be sent but it's getting late. Because I need to send notifications to thousands of device tokens. Even for 10 device tokens also not sending without thread.sleep(1000).
    Please suggest me what's wrong with my code.
    Here is my code snippet.

    public static void SendNotifications(List currentBrandNotications, long brandId)
    {
    byte[] appleCert = null;

            string p12File = @"aps_production_brand" + brandId.ToString().Trim() + ".p12";
            try
            {
                appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "P12\\" + p12File));               
            }
            catch (Exception ex)
            {
                logger.Debug("P12 certificate is not avilable for BrandId: " + brandId);
            }
    
            try
            {
                logger.Debug(" Send PushNotifications To Apple :- ");
    
                if (appleCert != null)
                {
                    // Configuration
                    var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production, appleCert, currentBrandNotications[0].P12Password);
    
                    // Create a new broker
                    var apnsBroker = new ApnsServiceBroker(config);
                    var fbs = new FeedbackService(config);
                    // Wire up events
                    apnsBroker.OnNotificationFailed += (Notification, aggregateEx) =>
                    {
                        //ScheduledNotification ScheduledNotification = new InstantPNScheduler.ScheduledNotification();
    
                        aggregateEx.Handle(ex =>
                        {
                            // See what kind of exception it was to further diagnose
                            if (ex is ApnsNotificationException)
                            {
                                var notificationException = (ApnsNotificationException)ex;
    
                                // Deal with the failed notification
                                var apnsNotification = notificationException.Notification;
                                var statusCode = notificationException.ErrorStatusCode;
                                logger.Debug("Apple Notification Failed: ID=" + apnsNotification.Identifier + " Code=" + statusCode);
    
                            }
                            else
                            {
                                // Inner exception might hold more useful information like an ApnsConnectionException           
                                logger.Debug(ex.InnerException.ToString());
                            }
                            // Mark it as handled
                            return true;
                        });
                    };
    
                    apnsBroker.OnNotificationSucceeded += (Notification) =>
                    {
                        logger.Debug("Apple Notification Sent!");                  
                    };
    
                    // Start the broker
                    apnsBroker.Start();  
    
                    foreach (ScheduledNotification notification in currentBrandNotications)
                         {                      
                        try
                        {
                            //logger.Debug("iOS Device token=" + notification.DeviceToken);                                             apnsBroker.QueueNotification(new ApnsNotification
                            {
                                   DeviceToken = notification.DeviceToken,
                                   Payload = JObject.Parse("{\"aps\":{\"alert\":\"" + notification.Message + "\",\"badge\":1,\"sound\":\"sound.caf\",\"BrandId\":\"" + brandId.ToString() + "\",\"notificationType\":\"Basic\",\"DeviceType\":\"" + notification.DeviceType + "\",\"DeviceToken\":\"" + notification.DeviceToken + "\",\"NotificationId\":\"" + notification.NotificationId + "\"}}")
    
                                });
                            }
                            Thread.Sleep(800);
                        }
                        catch (Exception ex)
                        {
    
                            logger.Debug(" SendPushNotificationToApple :- " + ex.Message);
                        }
                    }
                    // Stop the broker, wait for it to finish   
                    // This isn't done after every message, but after you're
                    // done with the broker
                    apnsBroker.Stop();
                }
    
            }
            catch (Exception ex)
            {
                logger.Debug("Error" + ex.Message);
            }
            finally
            {
                //apnsBroker = null;
            }
    
        }
    

    Thanks in advance.

  11. lukaspechar commented on Jun 30, 2016

    @lukaspechar

    @iinke any updates on this? I experienced this when dealing with a larger batch of notifications. I open the broker and send notification on a separate thread. Could this be the issue? Do you suggest I run the service on the main thread? The following are exceptions logged:

    Initially one for every notification:

    Source array was not long enough. Check srcIndex and length, and the array's lower bounds.

    at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) at System.Collections.Generic.Queue1.SetCapacity(Int32 capacity) at System.Collections.Generic.Queue1.Enqueue(T item) at PushSharp.Apple.ApnsConnection.Send(CompletableApnsNotification notification) at PushSharp.Apple.ApnsServiceConnection.<Send>d__2.MoveNext()

    followed by a bunch of:

    The ApnsNotificationErrorStatusCode: ConnectionError = 254,

  12. lukaspechar commented on Jul 27, 2016

    @lukaspechar

    @Redth Just checking if there are any updates on this issue. I am experiencing this even with a single broker. Would be great to understand what is going on. Any help would be appreciated. Thanks

  13. dehaaneric commented on Oct 4, 2016

    @dehaaneric

    I had this problem too. I solved it by checking the Push sharp (verbose) logging by setting:

            Log.ClearLoggers();
            Log.AddLogger(new PushLogger());
    

    It showed the error "Missing Push Token". And because I had a device without a (valid) pushtoken on top of my queue, the APNS server disconnected (all) connection(s) without question.

  14. lukaspechar commented on Oct 4, 2016

    @lukaspechar

    @tweek82 Thanks for your reply. How did you dequeue the device?

  15. dehaaneric commented on Oct 4, 2016

    @dehaaneric

    I check the push token before I add it to the queue. When token is invalid I directly update the devive in my database by just deleting it.

  16. lukaspechar commented on Oct 4, 2016

    @lukaspechar

    I am cleaning the expired devices using the FeedbackService class before I
    add any to the queue. Is there an extra check I need to make? How do you
    check the validity?

    On 4 October 2016 at 16:22, tweek82 notifications@github.com wrote:

    I check the push token before I add it to the queue. When token is invalid
    I directly update the devive in my database by just deleting it.

    —
    You are receiving this because you commented.
    Reply to this email directly, view it on GitHub
    #672 (comment),
    or mute the thread
    https://github.com/notifications/unsubscribe-auth/AAkJ3F2dvgRN-AUib61wbkhQYtXS9zh4ks5qwmE7gaJpZM4H9ixD
    .

  17. dehaaneric commented on Oct 4, 2016

    @dehaaneric

    Nothing fancy, just check IsNullOrWhitespace before queue'ing. Like this:

            foreach (var pushQueueItem in pushQueueItems.WithPrioSorting())
            {
                var pushServiceProviders = PushProviders.Single(x => x.DeviceType == pushQueueItem.AccountDeviceType);
    
                if (string.IsNullOrWhiteSpace(pushQueueItem.PushRegistrationId))
                {
                    CurrentLogger.Logger.Info("Missing devicetoken for: "+JsonConvert.SerializeObject(pushQueueItem));
                    PushResultIdCollectorService.AddFailedEntry(pushQueueItem.MessagePushRecipientId, DateTime.Now);
    
                    _accountDeviceService.RemovePushDeviceForRecipient(pushQueueItem.MessagePushRecipientId);
    
                    continue;
                }
    
                pushServiceProviders.Push(pushQueueItem);
            }
    
  18. lukaspechar commented on Oct 4, 2016

    @lukaspechar

    Hmm, ok so you had an empty device token for the device. I guess I'll have to enable the log to monitor what the issue is in my case as I cannot see a reason why my token would be empty or null. I only insert them when the user registers for push notifications from the device. So you used the following to enable logging...

    Log.ClearLoggers();
    Log.AddLogger(new PushLogger());
    

    I'll give it a go. Thanks for your help and swift replies 👍

  19. dehaaneric commented on Oct 4, 2016

    @dehaaneric

    No problem. Please share any of your apns-troubles and solutions. It might help me and others too.

  20. lukaspechar commented on Oct 5, 2016

    @lukaspechar

    Will do, once again thanks for your help @tweek82

  21. bidianqing commented on May 12, 2017

    @bidianqing

    Apns notification error: 'ConnectionError'

  22. bidianqing commented on May 12, 2017

    @bidianqing

    IIS Express is Succeeded and IIS is Failed

  23. faisalcse commented on Jul 11, 2017

    @faisalcse

    I am getting frequently connection error while sending Push to iOS.

    "Failed to Connect, check your firewall settings!

    at PushSharp.Apple.ApnsConnection.d__25.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
    at PushSharp.Apple.ApnsConnection.d__21.MoveNext()
    "
    Sometime it send and sometime it gives error.

    Please advice on resolution.

    Thanks in Advance.

  24. jimenaju commented on Jul 17, 2017

    @jimenaju

    Hello, I seem to be getting the same problem; I send 100 notifications and nothing is wrong, but when one of the tokens is wrong, Ialso get this exception often:
    PushSharp.Apple.ApnsNotificationException: Apns notification error: 'ConnectionError'

    Will insert code but keep in mind a lot of variables are useless, just using them to try to catch the problem...

    `using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Net.Security;
    using System.Net.Sockets;
    using System.Security.Authentication;
    using System.Security.Cryptography.X509Certificates;
    using System.Web;
    using System.Text;
    //using JdSoft.Apple.Apns.Feedback;
    using PushSharp.Apple;
    //using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;

    namespace PlaneSeats
    {
    public class APNS_Server
    { //doubts with Code, refer to:
    //https://stackoverflow.com/questions/37045299/issue-with-pushsharp-apple-notification-from-version-4-0-10-0-to-testflight/37133379

        public void pushNotifiaction(String indicadores)
        {
            string outputString;
            string notificationToken;
            string certificatePath = @"D:\Certificados\Certificados 2.p12";
            string certificatePassword = "";
            var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox, certificatePath, certificatePassword);
    
            //----------------------------------get tokens arr START---------------------------------------------------------------
    
            String token_iPhone = "1d26e6aade3755f3e98c94421dfa77b7576f5c6d203aed03d4b09afeccc43dce";
            String token_iPad = "2268ce35a15ec46aeef3dd2820e227ea5d9e0eaa163ef2cc33197230cdf93866";
            String bad_token_1 = "e85583e571b7fc3b712ffd33085ca10b42c3691500b96151e95dbe9fab5bee80";
            String bad_token_2 = "75343d0295c6345fd1a6283e7bc6bd66c5";
            String bad_token_3 = "75343d0295c6345fd1a6283e7bc6bd66c55650e0cce06bf6c3bd4b7a368fc3c7";
    
            int arrSize = 5;
            String[] tokenArr = new String[arrSize]; // Initialize.
            tokenArr[0] = token_iPhone;           // Element 1.
            tokenArr[1] = token_iPad;             // Element 2.
            tokenArr[2] = bad_token_1;
            tokenArr[3] = bad_token_2;
            tokenArr[4] = bad_token_3;
    
            //----------------------------------get tokens arr END-----------------------------------------------------------------
    
            var apnsBroker = new ApnsServiceBroker(config);
            // Wire up events
                apnsBroker.OnNotificationFailed += (notification, aggregateEx) =>
                {
                    outputString = String.Format("Apple Notification Failed Exception");
                    aggregateEx.Handle(ex =>
                    {
                        // See what kind of exception it was to further diagnose
                        if (ex is ApnsNotificationException)
                        {
                            notificationToken = "";
                            var notificationException = (ApnsNotificationException)ex;
                            ApnsNotificationErrorStatusCode errorCode = notificationException.ErrorStatusCode;
                            // Deal with the failed notification
                            var apnsNotification = notificationException.Notification;
                            var stCode = notificationException.ErrorStatusCode;
                            string statusCode = notificationException.ErrorStatusCode.ToString();
                            outputString = String.Format("Apple Notification Failed: ID={0}, Code=-{1}- Error code -{2}-.",
                            apnsNotification.Identifier, statusCode,errorCode);
                            outputString = statusCode;
                            outputString = notificationException.ErrorStatusCode.ToString();
                            notificationToken = apnsNotification.DeviceToken;
                            outputString = notificationToken;
    
                        }
                        else
                        {
                                // Inner exception might hold more useful information like an ApnsConnectionException           
                                outputString = String.Format("Apple Notification Failed for some unknown reason : {0}",
                                ex.InnerException);
                        }
                        // Mark it as handled
                        return true;
                    });
                };
                
                apnsBroker.OnNotificationSucceeded += (notification) =>
                {
                    notificationToken = "";
                    notificationToken = notification.DeviceToken;
                    outputString = String.Format("Apple Notification Sent: ID={0}.",
                    notification.Identifier);
                    outputString = "Apple Notification Sent!";
    
                };
    

    //--------------------------------FOR LOOP. STARTS HERE--------------------------------------------------------------------------------------
    //---------------------------------------------------------------------------------------------#763

            apnsBroker.Start();
            foreach (String token in tokenArr)
                {
                //http://desarrolloalpha.inegi.org.mx/app/api/indicadores//interna_v1_1/IOSToken/1ds23/2/json/[TU TOKEN]
                try{
                            
                            // Queue a notification to send
                            ApnsNotification notification = new ApnsNotification
                            {       DeviceToken = token,
                                    Payload = JObject.Parse("{\"aps\":{\"alert\":\"Jimena is testing apns feedback service!.\",\"badge\":\"1\"}}")
                                    };
                             notification.Tag = token;
                             outputString = "Notification queue";
                             apnsBroker.QueueNotification(notification);
                             //apnsBroker.Stop();
          
                }
                    catch (Exception e) {
                    outputString = "Notification queue exception";
                }
                
            }
            apnsBroker.Stop();
    

    //--------------------------------FOR LOOP. ENDS HERE--------------------------------------------------------------------------------------

    //-----------------------------------------------------------------------------------------------------------------------------------------------------------
    }
    }

    }
    `
    Also... if someone could tell me if the order is correct... I find it reaaally hard to understand as I´m new to... everything coding TT_TT

    Thanks!

  25. andrei1152 commented on Aug 17, 2017

    @andrei1152

    fixed this problem by setting config.internalBatchSize = int.MaxValue;
    I think the notification queue is not thread safe and when notifications are divided into batches, adding them to the queue raises this exception

  26. andersemil commented on Oct 13, 2017

    @andersemil

    Same issue here, I think I might have fixed it by locking notificationBatchQueueLock around the dequeueing, like this:

    			lock (notificationBatchQueueLock) {
    				while (notifications.Count > 0 && toSend.Count < Configuration.InternalBatchSize) {
    					var n = notifications.Dequeue ();
    					toSend.Add (n);
    				}
    			}
    
    
  27. EduardoKSibata commented on Jan 10, 2018

    @EduardoKSibata

    Maybe this problem can occur when the token is in invalid format.
    The token must be with Alphanumerics characters only, no white spaces or something else..
    It works for me.

  28. fatim commented on Aug 23, 2018

    @fatim

    I get the same error running the service in Azure WebApp. Same code works fine on my laptop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions