Code Monkey home page Code Monkey logo

pushsharp's Introduction

PushSharp v4.0

PushSharp is a server-side library for sending Push Notifications to iOS/OSX (APNS), Android/Chrome (GCM/FCM), Windows/Windows Phone, Amazon (ADM) and Blackberry devices!

PushSharp v3.0+ is a complete rewrite of the original library, aimed at taking advantage of things like async/await, HttpClient, and generally a better infrastructure using lessons learned from the old code.

PushSharp will now follow semver versioning, so major version numbers will go up as there are any breaking api changes.

Join the chat at https://gitter.im/Redth/PushSharp

AppVeyor CI Status

NuGet Version


Sample Usage

The API in v3.x+ series is quite different from 2.x. The goal is to simplify things and focus on the core functionality of the library, leaving things like constructing valid payloads up to the developer.

APNS Sample Usage

Here is an example of how you would send an APNS notification:

// Configuration (NOTE: .pfx can also be used here)
var config = new ApnsConfiguration (ApnsConfiguration.ApnsServerEnvironment.Sandbox, 
    "push-cert.p12", "push-cert-pwd");

// Create a new broker
var apnsBroker = new ApnsServiceBroker (config);
    
// Wire up events
apnsBroker.OnNotificationFailed += (notification, aggregateEx) => {

	aggregateEx.Handle (ex => {
	
		// See what kind of exception it was to further diagnose
		if (ex is ApnsNotificationException notificationException) {
			
			// Deal with the failed notification
			var apnsNotification = notificationException.Notification;
			var statusCode = notificationException.ErrorStatusCode;

			Console.WriteLine ($"Apple Notification Failed: ID={apnsNotification.Identifier}, Code={statusCode}");
	
		} else {
			// Inner exception might hold more useful information like an ApnsConnectionException			
			Console.WriteLine ($"Apple Notification Failed for some unknown reason : {ex.InnerException}");
		}

		// Mark it as handled
		return true;
	});
};

apnsBroker.OnNotificationSucceeded += (notification) => {
	Console.WriteLine ("Apple Notification Sent!");
};

// Start the broker
apnsBroker.Start ();

foreach (var deviceToken in MY_DEVICE_TOKENS) {
	// Queue a notification to send
	apnsBroker.QueueNotification (new ApnsNotification {
		DeviceToken = deviceToken,
		Payload = JObject.Parse ("{\"aps\":{\"badge\":7}}")
	});
}
   
// 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 ();

Apple Notification Payload

More information about the payload sent in the ApnsNotification object can be found here.

Apple APNS Feedback Service

For APNS you will also need to occasionally check with the feedback service to see if there are any expired device tokens you should no longer send notifications to. Here's an example of how you would do that:

var config = new ApnsConfiguration (
    ApnsConfiguration.ApnsServerEnvironment.Sandbox, 
    Settings.Instance.ApnsCertificateFile, 
    Settings.Instance.ApnsCertificatePassword);

var fbs = new FeedbackService (config);
fbs.FeedbackReceived += (string deviceToken, DateTime timestamp) => {
    // Remove the deviceToken from your database
    // timestamp is the time the token was reported as expired
};
fbs.Check ();

GCM/FCM Sample Usage

Here is how you would send a GCM/FCM Notification:

// Configuration GCM (use this section for GCM)
var config = new GcmConfiguration ("GCM-SENDER-ID", "AUTH-TOKEN", null);
var provider = "GCM";

// Configuration FCM (use this section for FCM)
// var config = new GcmConfiguration("APIKEY");
// config.GcmUrl = "https://fcm.googleapis.com/fcm/send";
// var provider = "FCM";

// Create a new broker
var gcmBroker = new GcmServiceBroker (config);
    
// Wire up events
gcmBroker.OnNotificationFailed += (notification, aggregateEx) => {

	aggregateEx.Handle (ex => {
	
		// See what kind of exception it was to further diagnose
		if (ex is GcmNotificationException notificationException) {
			
			// Deal with the failed notification
			var gcmNotification = notificationException.Notification;
			var description = notificationException.Description;

			Console.WriteLine ($"{provider} Notification Failed: ID={gcmNotification.MessageId}, Desc={description}");
		} else if (ex is GcmMulticastResultException multicastException) {

			foreach (var succeededNotification in multicastException.Succeeded) {
				Console.WriteLine ($"{provider} Notification Succeeded: ID={succeededNotification.MessageId}");
			}

			foreach (var failedKvp in multicastException.Failed) {
				var n = failedKvp.Key;
				var e = failedKvp.Value;

				Console.WriteLine ($"{provider} Notification Failed: ID={n.MessageId}, Desc={e.Description}");
			}

		} else if (ex is DeviceSubscriptionExpiredException expiredException) {
			
			var oldId = expiredException.OldSubscriptionId;
			var newId = expiredException.NewSubscriptionId;

			Console.WriteLine ($"Device RegistrationId Expired: {oldId}");

			if (!string.IsNullOrWhiteSpace (newId)) {
				// If this value isn't null, our subscription changed and we should update our database
				Console.WriteLine ($"Device RegistrationId Changed To: {newId}");
			}
		} else if (ex is RetryAfterException retryException) {
			
			// If you get rate limited, you should stop sending messages until after the RetryAfterUtc date
			Console.WriteLine ($"{provider} Rate Limited, don't send more until after {retryException.RetryAfterUtc}");
		} else {
			Console.WriteLine ("{provider} Notification Failed for some unknown reason");
		}

		// Mark it as handled
		return true;
	});
};

gcmBroker.OnNotificationSucceeded += (notification) => {
	Console.WriteLine ("{provider} Notification Sent!");
};

// Start the broker
gcmBroker.Start ();

foreach (var regId in MY_REGISTRATION_IDS) {
	// Queue a notification to send
	gcmBroker.QueueNotification (new GcmNotification {
		RegistrationIds = new List<string> { 
			regId
		},
		Data = JObject.Parse ("{ \"somekey\" : \"somevalue\" }")
	});
}
   
// Stop the broker, wait for it to finish   
// This isn't done after every message, but after you're
// done with the broker
gcmBroker.Stop ();

Components of a GCM/FCM Notification

GCM notifications are much more customizable than Apple Push Notifications. More information about the messaging concepts and options can be found here.

WNS Sample Usage

Here's how to send WNS Notifications:

// Configuration
var config = new WnsConfiguration ("WNS_PACKAGE_NAME", "WNS_PACKAGE_SID", "WNS_CLIENT_SECRET");

// Create a new broker
var wnsBroker = new WnsServiceBroker (config);

// Wire up events
wnsBroker.OnNotificationFailed += (notification, aggregateEx) => {

	aggregateEx.Handle (ex => {
	
		// See what kind of exception it was to further diagnose
		if (ex is WnsNotificationException notificationException) {
			Console.WriteLine ($"WNS Notification Failed: {notificationException.Message}");
		} else {
			Console.WriteLine ("WNS Notification Failed for some (Unknown Reason)");
		}

		// Mark it as handled
		return true;
	});
};

wnsBroker.OnNotificationSucceeded += (notification) => {
	Console.WriteLine ("WNS Notification Sent!");
};

// Start the broker
wnsBroker.Start ();

foreach (var uri in MY_DEVICE_CHANNEL_URIS) {
	// Queue a notification to send
	wnsBroker.QueueNotification (new WnsToastNotification {
		ChannelUri = uri,
		Payload = XElement.Parse (@"
			<toast>
				<visual>
					<binding template=""ToastText01"">
						<text id=""1"">WNS_Send_Single</text>
					</binding>  
				</visual>
			</toast>")
	});
}

// Stop the broker, wait for it to finish   
// This isn't done after every message, but after you're
// done with the broker
wnsBroker.Stop ();

How to Migrate from PushSharp 2.x to 3.x and higher

Please see this Wiki page for more information: https://github.com/Redth/PushSharp/wiki/Migrating-from-PushSharp-2.x-to-3.x

Roadmap

  • APNS - Apple Push Notification Service
    • Finish HTTP/2 support (currently in another branch)
  • GCM - Google Cloud Messaging
    • XMPP transport still under development
  • Other
    • More NUnit tests to be written, with a test GCM Server, and eventually Test servers for other platforms
    • New Xamarin Client samples (how to setup each platform as a push client) will be built and live in a separate repository to be less confusing

License

Copyright 2012-2016 Jonathan Dick

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

pushsharp's People

Contributors

1158626753 avatar 304notmodified avatar altima avatar antonvasilenko avatar baesfr avatar cheesebaron avatar dandude0 avatar dizlexik avatar dylanvdmerwe avatar eloe avatar elvis512 avatar filllip avatar fornever avatar grabmill avatar ibauersachs avatar jasongit avatar jdtaylor91 avatar kekekeks avatar kiichi avatar maorhayoun avatar nsoninextgen avatar omerkirk avatar paitoanderson avatar redth avatar robgibbens avatar samcook avatar scottisafool avatar steveheyman avatar t-telepko avatar yufeih avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pushsharp's Issues

Enhancemenets

Hi,

First,I want to say that I'm amazed with the latest version of PushSharp,you've done many enhancements on it since first version,great work

Second,A small modification on the code if it's possible,I've seen that events

OnDeviceSubscriptionIdChanged
OnDeviceSubscriptionExpired

are now returning PlatformType,that's great but I like to have that parameter in other events:

OnNotificationSent
OnNotificationSendFailure
OnChannelException

That's it :)

Sleep question

Hi,

Actually this is not an issue but a question I have about the way you implemented the sending/distributing mechanism.
Can you explain why you chose to use "Sleep" method instead of ResetEvent mechanism in the "Distributer" and "Sender" methods.
For example (Taken from PushChannelBase.Sender):

if (!queuedNotifications.TryDequeue(out notification))
{
//No notifications in queue, sleep a bit!
Thread.Sleep(250);
continue;
}

Thanks,
Tomer

I am doing something similar

Hey Jon,

I am doing something similar for my bachelors thesis and I am using your APNS-Sharp project for pushing to iPhone, if you are interested in seeing some code for WP7 and Android I would be able to provide some for you and when you eventually commit some code to GitHub I would be able to test for WP7, Android and iPhone if you need help with that.

/Tomasz

Broadcast Messages / Multiple Recipients

It would be nice to have some methods surrounding multiple notification recipients even if the platform doesn't truly support it, the library should do the work under the hood.

Blackberry Push Notification

Hello,

I can't find a sample for blackberry push Notification, and i want to use it., if anybody can help?

Thanks

APNS Feedback features

The current version of the code automatically calls the APNS feedback service every 10 minutes. This works fine if you have only a single server and like polling every 10 minutes, but doesn't if you have multiple servers. The first server to retrieve the feedback causes the record to be removed off of the APNS server.

In order to have multiple servers using the feedback service you need to have ONE of them poll the feedback server, then setup your own mechanism to ship and process them on the other servers (I use a simple XML file).

Also the current code converts the received UTC timestamp from APNS to server local time. Need an option to retrieve the UTC feedback time since our system does everything in UTC. During the fall DST shift a conversion from local to UTC time is ambiguous so simply converting local back to UTC doesn't work during one hour every year....sigh.

I've added two new configuration values to the ApplePushChannelSettings class and associated logic in the ApplePushService code to address these issues. Setting FeedbackIntervalMinutes = 0 stops feedback processing, and setting the FeedbackTimeIsUTC flag to true causes the times reported by feedback service to be in UTC instead of local.

Fixes for these issues are in my fork of the repo.

Should GCM NotRegistered event also raise NotificationSendFailure

In GcmPushChannel, when the DeviceSubscriptionExpired event is raised you are also raising the NotificationSendFailure event.

IMHO it would be better to ONLY raise the subscription expired event in this instance. As an example, I've got an event handler that logs an error to our error log attached to the SendFailure event (since I want to capture any network/service issues). Having the fact that an end-user uninstalled the app should not end up in my error log since it's an expected event that gets handled in the DeviceSubscriptionExpired handler. I've got code in there to suppress the logging of this event, but I'd rather not have to do this. Also, the suppression logic ends up feeling a bit sloppy as well since the GcmMessageTransportException doesn't include the ResponseStatus enumeration, but just serializes it's value as the message, detecting the "type" of exception based on what is intended to be a human-readable description feels a bit wrong....the quickest fix for this would be to actually include the ResponseStatus enum member in the exception.

Just a couple of suggestions, since they are behavioral changes I'll leave it up to you whether to include them.

Is there any optimized numbers of message should be used during one go

If I need to send out say 100 or 1000 or more messages to Android devices, what is the best way to use this Library.

Always we need call push.StartGoogleCloudMessagingPushService() for each call or instantiate it only once and call push.QueueNotification() for each message.

Is there any other advise ?

Thanks in advance

Never destroy the channels

I have a problem, that the channels are never destroyed.

Messages are delivered, but the event (OnChannelDestroyed) is not called and the event (OnChannelCreated) always appears appears, increasing the channels.

5 push email sent to the same device at the same time (the problem happens)
Now if I send 1 push after about 2 seconds, send another, the channel is created and then destroyed.

Here is a code example:

        private static void Main(String[] args)
        {
                    var pushService = new PushService();

                    pushService.Events.OnChannelCreated += Events_OnChannelCreated;
                    pushService.Events.OnChannelDestroyed += Events_OnChannelDestroyed;
                    pushService.Events.OnChannelException += Events_OnChannelException;
                    pushService.Events.OnDeviceSubscriptionExpired += Events_OnDeviceSubscriptionExpired;
                    pushService.Events.OnDeviceSubscriptionIdChanged += Events_OnDeviceSubscriptionIdChanged;
                    pushService.Events.OnNotificationSendFailure += Events_OnNotificationSendFailure;
                    pushService.Events.OnNotificationSent += Events_OnNotificationSent;

                    var channel = new PushSharp.Apple.ApplePushChannelSettings(false, "C:\\ios.p12", "password");
                    pushService.StartApplePushService(channel);

                    for (Int32 i = 1; i<= 5; i++)
                    {
                                var notification = new AppleNotification("token_device");

                                pushService.QueueNotification(not.WithAlert(i));
                    }

                    Console.ReadKey();
        }

        private void Events_OnNotificationSent(Notification notification)
        {
                    Console.WriteLine("Events_OnNotificationSent: " + (notification as AppleNotification).Payload.Alert);
        }

        private void Events_OnNotificationSendFailure(Notification notification, Exception notificationFailureException)
        {
                    Console.WriteLine("Events_OnNotificationSendFailure: " + (notification as AppleNotification).Payload.Alert + " - " + notificationFailureException.Message);
        }

        private void Events_OnDeviceSubscriptionIdChanged(PlatformType platform, string oldDeviceInfo, string newDeviceInfo, Notification notification = null)
        {
                    Console.WriteLine("Events_OnDeviceSubscriptionIdChanged: " + oldDeviceInfo + " -> " + newDeviceInfo);
        }

        private void Events_OnDeviceSubscriptionExpired(PlatformType platform, string deviceInfo, Notification notification = null)
        {
                    Console.WriteLine("Events_OnDeviceSubscriptionExpired: " + deviceInfo);
        }

        private void Events_OnChannelException(Exception exception, PlatformType platformType, Notification notification = null)
        {
                    Console.WriteLine("Events_OnChannelException: " + exception.Message);
        }

        private void Events_OnChannelDestroyed(PlatformType platformType, int newChannelCount)
         {
                Console.WriteLine("Events_OnChannelDestroyed: " + newChannelCount);
        }

        private void Events_OnChannelCreated(PlatformType platformType, int newChannelCount)
        {
                Console.WriteLine("Events_OnChannelCreated: " + newChannelCount);
        }

pass a tag object to all event callbacks

Hello,

I know that there's a Tag object to pass an user-defined object to OnNotificationSent and OnNotificationSendFailure event callbacks. However, it is not possible to get Notification containing the Tag object in other three callbacks - OnDeviceSubscriptionExpired, OnDeviceSubscriptionIdChanged and OnChannelException.

Is there an intended reason behind this. If not, do you have a plan to pass Notification to the above three callbacks as well?

thanks,
Jae

GCMPushChannel reporting incorrect platform.

Looks like you've got a copy-and-paste error in GCMPushChannel.

In the RaiseDeviceSubscriptionIdChanged and RaiseDeviceSubscriptionExpired calls you're reporting PlatformType.AndroidC2dm instead of AndroidGcm

Fix is in my fork....

Notification received but contents are empty!

Hi there:
In my app, i have successfully sent the push notification from the server side, but when retrieved it from the client side, the content of the message (in JSON format) became empty... Why??

Server side code:

//Create our service
PushService push = new PushService();
//Create our service
push = new PushService();

        //Wire up the events
        push.Events.OnDeviceSubscriptionExpired += new PushSharp.Common.ChannelEvents.DeviceSubscriptionExpired(Events_OnDeviceSubscriptionExpired);
        push.Events.OnDeviceSubscriptionIdChanged += new PushSharp.Common.ChannelEvents.DeviceSubscriptionIdChanged(Events_OnDeviceSubscriptionIdChanged);
        push.Events.OnChannelException += new PushSharp.Common.ChannelEvents.ChannelExceptionDelegate(Events_OnChannelException);
        push.Events.OnNotificationSendFailure += new PushSharp.Common.ChannelEvents.NotificationSendFailureDelegate(Events_OnNotificationSendFailure);
        push.Events.OnNotificationSent += new PushSharp.Common.ChannelEvents.NotificationSentDelegate(Events_OnNotificationSent);

        push.StartGoogleCloudMessagingPushService(new GcmPushChannelSettings("1XXXXX1194", "AIzaSyCN0XXXXXXXXXXXXXXldveN0", "com.XXXX.XXXX"));

        GcmNotification notification = NotificationFactory.AndroidGcm();
        notification.ForDeviceRegistrationId(deviceToken);
        notification.WithCollapseKey("NONE");
        notification.WithJson("{\"alert\":\"" + alert + "\",\"badge\":\"" + badge + "\"}");
        push.QueueNotification(notification);
        //Stop and wait for the queues to drains
        push.StopAllServices(true);

Client side code:

document.addEventListener
(
'push-notification',
function (event)
{
console.log('Notification:::' + event);
}
)

Strongly-named NuGet assemblies

Is it possible to strongly name the assemblies on NuGet? Anyone referencing these assemblies in strongly named projects won't be able to compile. Thanks!

Bug on DetectProduction

Redth-PushSharp-bdfb871\PushSharp.Apple\ApplePushChannelSettings.cs Line: 71 on

The "this.Certificate" seems always null to cause production check always false
Kind of obvious to me that it should be using the "certificate" parameter as passed in.

=== current ===
public bool DetectProduction(X509Certificate2 certificate)
{
bool production = false;

        if (this.Certificate != null)
        {
            var subjectName = this.Certificate.SubjectName.Name;

            if (subjectName.Contains("Apple Production IOS Push Services"))
                production = true;
        }

        return production;
    }

=== suggest ===
public bool DetectProduction(X509Certificate2 certificate)
{
bool production = false;

        if (certificate != null)
        {
            var subjectName = certificate.SubjectName.Name;

            if (subjectName.Contains("Apple Production IOS Push Services"))
                production = true;
        }

        return production;
    }

Crashing as part as a Service

It crashes on .Common.PushChannelBase after sending groups of notifications. The groups are sent with some minutes as interval, each push.QueueNotification() with 3 seconds interval. Is there a solution for this?

Stack trace:

Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Threading.Tasks.TaskSchedulerException
Stack:
at System.Threading.Tasks.Task.ScheduleAndStart(Boolean)
at System.Threading.Tasks.Task.Start(System.Threading.Tasks.TaskScheduler)
at PushSharp.Common.PushChannelBase..ctor(PushSharp.Common.PushChannelSettings, PushSharp.Common.PushServiceSettings)
at PushSharp.Apple.ApplePushChannel..ctor(PushSharp.Apple.ApplePushChannelSettings, PushSharp.Common.PushServiceSettings)
at PushSharp.Apple.ApplePushService.CreateChannel(PushSharp.Common.PushChannelSettings)
at PushSharp.Common.PushServiceBase1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].SpinupChannel() at PushSharp.Common.PushServiceBase1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].CheckScale()
at PushSharp.Common.PushServiceBase`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].<.ctor>b__0(System.Object)
at System.Threading._TimerCallback.TimerCallback_Context(System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading._TimerCallback.PerformTimerCallback(System.Object)

apple push from hosted asp.net fails on obtaining permission KeyContainerPermission

Request for the permission of type 'System.Security.Permissions.KeyContainerPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

This works fine on my development machine but fails when I push to my shared host (hostgator).
The call that is failing on is
new X509Certificate2(certificateData, certificateFilePwd,
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable)

I understand why it is failing but not sure what to do about it. I am surprised no one else has encountered this.

Question: Is it possible to pass data to the intent via the uiIntent?

In Android, is it possible to pass data to the target Activity via the uiIntent which is set in the "PushService.cs"?

In the example, the uiIntent appears to only be used to launch the Activity, but the Activity gets all its data from the prefs database.

I tried setting an intent bundle, and the bundle initially goes through correctly to the target activity, but subsequent activities pass only the originally set intent.

I suppose if the only method is to use something like the prefs database, I should have my uiIntent point to an intermediate activity which knows it's being launched from a notification, and not "normally" from within the application.

Am I interpreting this correctly? Or is it a bug that the intent doesn't seem to refresh properly to the target activity on repeated notifications?

PushSharp and Azure

I've been using PushSharp in a .NET 4 WebAPI-application for a while on my local development-machine for sending push notifications to my iOS app, and it works great. However when i publish it to Azure, the OnChannelException-event is called and i get the exception below. I am using the latest package from NuGet, 1.0.17. Any idea why this happens?

The credentials supplied to the package were not recognized
at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule, String package, CredentialUse intent, SecureCredential scc)
at System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse credUsage, SecureCredential& secureCredential)
at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at PushSharp.Apple.FeedbackService.Run(ApplePushChannelSettings settings, CancellationToken cancelToken)
at PushSharp.Apple.ApplePushService.<>c__DisplayClass2.<.ctor>b__0(Object state)

He says he sent even without internet

Doing some tests I found another problem, here we go:

To see the problem happen, I put a push to send every 10 seconds.

When I put in the queue, it would print on the screen saying Queued
Once sent, the event would print screen Events_OnNotificationSent

I run the code below.
He sends the first (get immediately on the iphone).
Just when I get the event Events_OnNotificationSent, retreat the network cable from my macbook (completely lost connection).

Ai after 10 seconds, it says Queued
After I get: Events_OnNotificationSent

That is not sent, and he says he sent.

Queued: 786578342
Events_OnNotificationSent: 786578342
(Here I pulled out the cable before the end of 10 seconds)
Queued: 810948234
Events_OnNotificationSent: 810948234
(Still with the cable removed)
Queued: 532534543
Events_OnNotificationSent: 532534543
(Still with the cable removed)
Here now he starts giving error.
If I put the cable back he sends everyone, even those who gave as sent.

Another question, at what time the event runs OnDeviceSubscriptionExpired?

Here is a code example:

        private static void Main(String[] args)
        {
                    var pushService = new PushService();

                    pushService.Events.OnChannelCreated += Events_OnChannelCreated;
                    pushService.Events.OnChannelDestroyed += Events_OnChannelDestroyed;
                    pushService.Events.OnChannelException += Events_OnChannelException;
                    pushService.Events.OnDeviceSubscriptionExpired += Events_OnDeviceSubscriptionExpired;
                    pushService.Events.OnDeviceSubscriptionIdChanged += Events_OnDeviceSubscriptionIdChanged;
                    pushService.Events.OnNotificationSendFailure += Events_OnNotificationSendFailure;
                    pushService.Events.OnNotificationSent += Events_OnNotificationSent;

                    var channel = new PushSharp.Apple.ApplePushChannelSettings(false, "C:\\ios.p12", "password");
                    pushService.StartApplePushService(channel);

                    while (true)
                    {
                                var notification = new AppleNotification("token_device");
                                var ticks = DateTime.Now.Ticks;

                                pushService.QueueNotification(not.WithAlert(ticks));

                                Console.WriteLine("Queued: " + ticks.ToString());

                                Thread.Sleep(10000);
                    }
        }

        private void Events_OnNotificationSent(Notification notification)
        {
                    Console.WriteLine("Events_OnNotificationSent: " + (notification as AppleNotification).Payload.Alert);
        }

        private void Events_OnNotificationSendFailure(Notification notification, Exception notificationFailureException)
        {
                    Console.WriteLine("Events_OnNotificationSendFailure: " + (notification as AppleNotification).Payload.Alert + " - " + notificationFailureException.Message);
        }

        private void Events_OnDeviceSubscriptionIdChanged(PlatformType platform, string oldDeviceInfo, string newDeviceInfo, Notification notification = null)
        {
                    Console.WriteLine("Events_OnDeviceSubscriptionIdChanged: " + oldDeviceInfo + " -> " + newDeviceInfo);
        }

        private void Events_OnDeviceSubscriptionExpired(PlatformType platform, string deviceInfo, Notification notification = null)
        {
                    Console.WriteLine("Events_OnDeviceSubscriptionExpired: " + deviceInfo);
        }

        private void Events_OnChannelException(Exception exception, PlatformType platformType, Notification notification = null)
        {
                    Console.WriteLine("Events_OnChannelException: " + exception.Message);
        }

        private void Events_OnChannelDestroyed(PlatformType platformType, int newChannelCount)
         {
                Console.WriteLine("Events_OnChannelDestroyed: " + newChannelCount);
        }

        private void Events_OnChannelCreated(PlatformType platformType, int newChannelCount)
        {
                Console.WriteLine("Events_OnChannelCreated: " + newChannelCount);
        }

C2DM: OnChannelException firing for all not ok responses

This issue relates to #18 (C2DM : OnChannelException is fired on "not registered" devices).

When C2DM receives any response besides ok, it throws a MessageTransportException (line 184 of C2dmMessageTransportAsync) which is caught and sent to UnhandledException (line 128). So it never gets to AndroidPushChannel.transport_MessageResponseReceived and pushed to the correct event. Looks like a carry over from C2dmSharp.Server.

Separate Nuget request, is there any way to set the Newtonsoft.Json dependency to >= 4.5.7 so it can be updated as Newtonsoft releases?

Apple service : OnDeviceSubscriptionExpired

I've noticed when I send push notifications to Apple devices the library usually call OnNotificationSent event and this is normal,but here is the annoying part,the library sometimes call another event after it:
OnDeviceSubscriptionExpired,and the notification parameter is null/nothing

  1. Why would the library call [OnNotificationSent] though the device may have uninstalled the application ?

  2. Notification parameter is really important,why it wouldn't always be returned when event OnDeviceSubscriptionExpired is called?

**My case:
I noticed that apple devices that have 2 or more of my applications MAY send to my server the same device token,if a user uninstalled application X and kept Application Y and both uses the same device token how Am I suppose to remove the device (in Database) from the notifications list for application x without removing it from the notification list of application Y ? I need a flag/key or something (like application ID for instance),I've already handled this case by adding the application ID within customitems of apple notification object,I expected to read the notification object in OnDeviceSubscriptionExpired and from there I can remove the device from the list/DB using deviceinfo(devicetoken) and app ID (in customitems of notification object),but now since this method is called and notification object is null I don't know how Am I suppose to handle the case,I hope you got my point :)

P.S: Sorry for my english ^^;

Cryptography Error

Hi,

When I use your Apple push notifications, I get this error:

System.Security.Cryptography.CryptographicException:

Input data cannot be coded as a valid certificate. ---> System.Exception: Input data cannot be coded as a valid certificate.

at Mono.Security.X509.X509Certificate.Parse (System.Byte[] data) [0x00041] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs:113
--- End of inner exception stack trace ---
at Mono.Security.X509.X509Certificate.Parse (System.Byte[] data) [0x00352] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs:207
at Mono.Security.X509.X509Certificate..ctor (System.Byte[] data) [0x0003e] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs:225
at System.Security.Cryptography.X509Certificates.X509Certificate.Import (System.Byte[] rawData, System.String password, X509KeyStorageFlags keyStorageFlags) [0x000b4] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509Certificate20.cs:254
at System.Security.Cryptography.X509Certificates.X509Certificate2.Import (System.Byte[] rawData, System.String password, X509KeyStorageFlags keyStorageFlags) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs:441
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor (System.Byte[] rawData, System.String password, X509KeyStorageFlags keyStorageFlags) [0x00011] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs:87
at PushSharp.Apple.ApplePushChannelSettings..ctor (Boolean production, System.Byte[] certificateData, System.String certificateFilePwd) [0x00000] in :0
at MenuFinderMT.Push.DoPush () [0x00020] in /Users/josephanderson/Projects/Commercial/MenuFinder/jmaweb_menuf/MenuFinderMT/Code/Push.cs:19
at MenuFinderMT.AboutUniversalController.ViewDidLoad () [0x0004f] in /Users/josephanderson/Projects/Commercial/MenuFinder/jmaweb_menuf/MenuFinderMT/Screens/Universal/AboutUniversalController.cs:39
at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend_IntPtr_bool (intptr,intptr,intptr,bool)
at MonoTouch.UIKit.UINavigationController.PushViewController (MonoTouch.UIKit.UIViewController viewController, Boolean animated) [0x00021] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UINavigationController.g.cs:134
at MenuFinderMT.RestaurantSearchUniversalController.btnAbout_Click (System.Object sender, System.EventArgs e) [0x00000] in /Users/josephanderson/Projects/Commercial/MenuFinder/jmaweb_menuf/MenuFinderMT/Screens/Universal/RestaurantSearchUniversalController.cs:80
at MonoTouch.UIKit.UIBarButtonItem+Callback.Call (MonoTouch.Foundation.NSObject sender) [0x00010] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIBarButtonItem.cs:23
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)

Is my code correct?

public void DoPush()
{
var push = new PushService();
var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MenuFinderMT.PushCert.Development.p12"));
var settings = new ApplePushChannelSettings(false, appleCert, "xxx");
push.StartApplePushService(settings);
string token = NSUserDefaults.StandardUserDefaults.StringForKey("PushDeviceToken");
push.QueueNotification(
NotificationFactory.Apple().ForDeviceToken(token)
.WithAlert("Test alert")
.WithSound("default")
.WithBadge(7)
);
}

Channel has already been signaled to stop

Hello,

I've created a small webpage to send push notifications. All works fine when running on my development machine in IIS Express.
When I deploy the site to an IIS server I get the following error:

Channel has already been signaled to stop
Object name: 'Channel'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ObjectDisposedException: Channel has already been signaled to stop
Object name: 'Channel'.

Stacktrace:
[ObjectDisposedException: Channel has already been signaled to stop
Object name: 'Channel'.]
PushSharp.Common.PushChannelBase.QueueNotification(Notification notification, Boolean countsAsRequeue) in c:\Dropbox\GitHub\PushSharp\PushSharp.Common\PushChannelBase.cs:87
PushSharp.Apple.ApplePushChannel.SendNotification(Notification notification) in c:\Dropbox\GitHub\PushSharp\PushSharp.Apple\ApplePushChannel.cs:107
PushSharp.Common.PushChannelBase.Sender() in c:\Dropbox\GitHub\PushSharp\PushSharp.Common\PushChannelBase.cs:121
System.Threading.Tasks.Task.Execute() +130

[AggregateException: One or more errors occurred.]
System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken) +1738
System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout) +84
PushSharp.Common.<>c__DisplayClass5.b__4(PushChannelBase channel) in c:\Dropbox\GitHub\PushSharp\PushSharp.Common\PushServiceBase.cs:68
System.Threading.Tasks.<>c__DisplayClassf`1.b__c() +4399023
System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) +24
System.Threading.Tasks.<>c__DisplayClass7.b__6(Object ) +406

[AggregateException: One or more errors occurred.]
System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) +5842467
System.Threading.Tasks.Task.Wait() +44
System.Threading.Tasks.Parallel.ForWorker(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action1 body, Action2 bodyWithState, Func4 bodyWithLocal, Func1 localInit, Action1 localFinally) +5772041 System.Threading.Tasks.Parallel.ForEachWorker(IEnumerable1 source, ParallelOptions parallelOptions, Action1 body, Action2 bodyWithState, Action3 bodyWithStateAndIndex, Func4 bodyWithStateAndLocal, Func5 bodyWithEverything, Func1 localInit, Action1 localFinally) +524 System.Threading.Tasks.Parallel.ForEach(IEnumerable1 source, Action`1 body) +188
PushSharp.Common.PushServiceBase.Stop(Boolean waitForQueueToFinish) in c:\Dropbox\GitHub\PushSharp\PushSharp.Common\PushServiceBase.cs:71
System.Threading.Tasks.Task.Execute() +130

[AggregateException: One or more errors occurred.]
System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken) +1738
System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout) +84
System.Threading.Tasks.Task.WaitAll(Task[] tasks) +39
Vdb.GG.Toyota.EUNewsfeed.Webservice.NotificationManager.Dispose() in E:\Projects\TFS\Novado\ShortTerm\Toyota\EUNewsfeed\Webservice\NotificationManager.cs:40
Vdb.GG.Toyota.EUNewsfeed.Webservice.Notification.OnUnload(Object sender, EventArgs eventArgs) in E:\Projects\TFS\Novado\ShortTerm\Toyota\EUNewsfeed\Webservice\Notification.aspx.cs:27
System.Web.UI.Control.UnloadRecursive(Boolean dispose) +160
System.Web.UI.Page.UnloadRecursive(Boolean dispose) +24
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +11426238
System.Web.UI.Page.ProcessRequest() +269
System.Web.UI.Page.ProcessRequest(HttpContext context) +167
ASP.notification_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\e6258f78\c6c584c\App_Web_4k12j52l.0.cs:0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +625
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270

In the NotificationManager Dispose method I call: pushService.StopAllServices(true);
When I remove this line, I no longer get the exception, but the message is not sent either.

If I don't call Dispose in my page unload handler, messages are also not sent.

What am I doing wrong?

Feedback on AppleService

Hi,

In my code I fetch from my database all notifications that must be sent to different users who installed different types of my applications, I was wondering,what would happen if I have a code like this :

PushSrv.StartApplePushService(AppOneChannelSettings)
PushSrv.QueueNotification(NotificationForAppOne)

PushSrv.StartApplePushService(AppTwoChannelSettings)
PushSrv.QueueNotification(NotificationForAppOne)
PushSrv.QueueNotification(NotificationForAppTwo)
  1. Will PushSrv starts 2 Apple services ? or does it dispose/close ApplePushService for AppOne then create one for AppTwo?
    Edit: OK I think the library do the later.
  2. If the library do the later (close/dispose) then what would happen to the notifications for AppOne? does the library wait for the notifications for AppOne to be sent or do I have to handle this in my code?
  3. What does WithTag() do ? I've searched everywhere and I couldn't find an example or even a description on it.

Sent messages are not received

Hi,
if you try to send some messages in a short time, like for(...) QueueNotification()
not all messages are sent to the device

C2DM notregistered error handled incorrectly

In our testing, if the app is uninstalled from our test devices, we get a "notregistered" error back from C2DM instead of "invalidregistration". The existing code ends up throwing a generic "MessageTransportException" in this event, which doesn't allow the processing to fall down into the logic to raise the DeviceSubscriptionExpired event. (which you have to do in order to get at the problem device identifier).

Added logic in C2dmMessageTransportAsync to suppress the throw if we've got a device ID problem, and logic in AndroidPushChannel to raise the SubscriptionExpired event if you get either an invalid registration or a not registered problem (since in both cases you want to stop sending pushes to that device until you get a good device identifier).

Fixes are in my fork....

certificate problem in asp.net page

hello,

i am using ApplePushService in a asp.net webpage (vb.net)

i always get an certificate error in: ApplePushChannel.cs

stream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback((sender, cert, chain, sslPolicyErrors) => { return true; }),
new LocalCertificateSelectionCallback((sender, targetHost, localCerts, remoteCert, acceptableIssuers) =>
{
return certificate;
}));

this exception happens at the 2. time the routine was called (return certificate;)
//win32exception
something like: The credentials that were given to the package were not recognized
(sorry my error text is in german)

this code works in my winforms application well.

i have changed this code for testring to

stream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback((sender, cert, chain, sslPolicyErrors) => { return true; }),
new LocalCertificateSelectionCallback((sender, targetHost, localCerts, remoteCert, acceptableIssuers) =>
{
var appleCert = System.IO.File.ReadAllBytes(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "certificates/MYCERT.p12"));
X509Certificate2 cert = new X509Certificate2(appleCert, "MYPASSWORD",
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
return cert ;
}));

and this works well. its not very good solution but maybe it helps you to find the problem

GCMBaseIntentService requires a (protected) default constructor in Release mode

This is difficult to explain, so it is best to refer to this issue:

https://bugzilla.novell.com/show_bug.cgi?id=655342

When you compile Mono for Android projects in release mode, it will perform optimized linking and remove unused SDK code.
One of these optimizations can be the removal of the default constructor of the java IntentService class.

When your custom intent service is instantiated, it first instantiates the java IntentService object using it's default constructor, which is no longer there, and therefore throws an exception.

The way we fixed this is to put a protected default constructor in the GCMBaseIntentService, which tells the Mono compiler not to optimize out the default constructor on the java IntentService.

We could probably also have solved this by creating a dummy class that does something similar, but it would be useful if GCMBaseIntentService didn't have this problem itself.

If that is clear as mud, let me know and I can (try) elaborate.

Google Auth Token timeout using C2DM with no way to call refresh

Have a situation where the C2DM Auth Token has timed out (assuming since it is after long periods of time between sends), when this happens I get the InvalidAuthenticationTokenTransportException exception, but do not have a way to iterate the channels and call RefreshGoogleAuthToken.

Maybe the RefreshGoogleAuthToken could be called the first time the error is received and the push re-queued?

Other options?

Brian

HTML5 Push Notifications

Not sure what is involved or possible here, but HTML5 push notifications should be investigated

Apple NotificationFailureException no message details

Hi,

I suggest to set the NotificationFailureExceptions' exception message in the constructor.
Currently if this exception was raised , the client should check the type of the exception in order to get additional info, such as the ErrorStatusDescription.

We can just pass the ErrorStatusDescription as the message to the base constructor.

Tomer

Apple service isn't working

Apple service doesn't send any notification and none of the PushService events are firing (OnNotificationSendFailure or any of the other events) that tells me what happened to the notification ( Success,failed ) ,I don't know what I'm missing though I followed the examples

Nuget packages after important updates

Hello! Can you push please a new nugget package containing the updates for Google Cloud Messaging? It would be great if nugget repos are updated frequently based on evolution of the work.

How to check service status?

Is there a way to know if a service is running or not? i.e. Check if ApplePushService is running,stopped or not started.

Socks Proxy

We are running in to an issue in deployment with the network team not wanting to open ports 2195 and 2196 for Apple communication. They are pretty adamant that they want us to use a SOCKS proxy, I think it may be possible and am looking at it. There is this library under MIT license http://sourceforge.net/projects/starksoftproxyc/ that could be included in this library to add option to PushSharp allowing proxying of Apple connection. I am going to work on the code for this but it would be nice to get it incorporated in to the final version also so we don't lose any future changes to this library.

PushSharp on Mono in MVC

Hi there

I'm doing a push from a MVC3 app, running on a Linode.

If I do it locally (ie, on my windows machine) it works fine. Same code on the linode says its sent it, but it never gets the Events_OnNotificationSent event fire.

I have the pushservice object setup as a static, but I've also tried it local to the controller method.

Any ideas? Any way to see error logs from it? I'm not getting a Events_OnNotificationSendFailure (or anything else) either. It just disappears into the ether.

I'm going to try it on my mac tonight to see if it's a mono issue, but have you had it working on Mono on a server at all?

Thanks

Nic

Abstract implementation of PushServices in PushService dll

Currently the PushService library contains concrete instances of Apple.ApplePushService etc, because of these references the deployment needs to contain every dll regardless of usage or not. If the use of these classes in PushService were abstracted to their base class then you could create and pass in the Apple.ApplePushService to the PushService class that way you would not have to deploy the Blackberry, Windows, etc. other DLL's if you were not using those push methods.

Apple Push suddenly stopped working

Hi!

In my development environment everything works just fine.
Today the app runing the PushSharp in my Server (which is still production = false and uses the matching sandbox certificate) suddenly crashed with the following error:


Application: Pusher.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AggregateException
Stack:
at System.Threading.Tasks.Task.WaitAll(System.Threading.Tasks.Task[], Int32, System.Threading.CancellationToken)
at PushSharp.Apple.ApplePushChannel.Stop(Boolean)
at PushSharp.Common.PushServiceBase1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].ScaleChannels(PushSharp.Common.ChannelScaleAction, Int32) at PushSharp.Common.PushServiceBase1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].CheckScale()
at PushSharp.Common.PushServiceBase`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].<.ctor>b__0(System.Object)
at System.Threading.TimerQueueTimer.CallCallbackInContext(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.TimerQueueTimer.CallCallback()
at System.Threading.TimerQueueTimer.Fire()
at System.Threading.TimerQueue.FireNextTimers()

at System.Threading.TimerQueue.AppDomainTimerCallback()

and after that happened I couldn't send any more apple notifications.
It just won't raise any events, it just writes down:

"Channel Created for: Apple Channel Count: 2"

and that's it.

Any ideas why this suddenly stopped?

My code is as following:


//Create PushSharp service
push = new PushService();

        //Bind PushSharp events
        push.Events.OnNotificationSent += new PushSharp.Common.ChannelEvents.NotificationSentDelegate(Events_OnNotificationSent);
        push.Events.OnDeviceSubscriptionExpired += new PushSharp.Common.ChannelEvents.DeviceSubscriptionExpired(Events_OnDeviceSubscriptionExpired);

        //Wire up the events
        push.Events.OnDeviceSubscriptionIdChanged += new PushSharp.Common.ChannelEvents.DeviceSubscriptionIdChanged(Events_OnDeviceSubscriptionIdChanged);
        push.Events.OnChannelException += new PushSharp.Common.ChannelEvents.ChannelExceptionDelegate(Events_OnChannelException);
        push.Events.OnNotificationSendFailure += new PushSharp.Common.ChannelEvents.NotificationSendFailureDelegate(Events_OnNotificationSendFailure);
        push.Events.OnChannelCreated += new PushSharp.Common.ChannelEvents.ChannelCreatedDelegate(Events_OnChannelCreated);
        push.Events.OnChannelDestroyed += new PushSharp.Common.ChannelEvents.ChannelDestroyedDelegate(Events_OnChannelDestroyed);

        var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Misc.GetConfig("SandBoxCertificatePath")));

        push.StartApplePushService(new ApplePushChannelSettings(false, appleCert, Misc.GetConfig("SandBoxCertificatePassword")));

        push.QueueNotification(NotificationFactory.Apple()
                            .ForDeviceToken(popQueuePush.ExternalDeviceTokenUID)
                            .WithAlert(popQueuePush.Content)
                            .WithSound("default")
                            .WithBadge(0));

Thanks!

100% cpu consumption in ApplePushChannel.Cleanup

There is a while (true) in ApplePushChannel.Cleanup.

Inside the while block is a condition if (wasRemoved) Thread.Sleep(250).

As wasRemoved = false is defined outside of the while block, it is possible for wasRemoved to be set to true, resulting in the while loop spinning and consuming all CPU.

I believe the easiest way to fix this is to define bool wasRemoved inside the while (true) block.

collapse_key=do_not_collapse

Apparently when leaving the collapse key blank for Android "do_not_collapse" is sent instead. This is in and of itself a collapse key, essentially all messages have this so GCM assumes they are all on the same chain. To get around this issue I am specifying a Guid for the collapse key so it is different every time, but this should also not be necessary. I have sent requests (when I manually coded this class before using your library) to Google without it.

If not specified the library should not send a collapse key.

FeedbackService

I'm trying to query Apple Feedbackservice without no result.

I put FeedbackService.Run in a BackgroundWorker on a WPF app.
So, bgWorker.RunWorkerCompleted never called.

I need to implement some timeout function?

Get all IDs

Hi Jon,

Not sure how to contact you directly.

If I want to send a push notification to everyone that is using my iOS app, how do I do that? Do I need the ID of each device? If so, how do I obtain that information?

I have a Win8 app under review from Microsoft. Do you need any help with documentation or testing for Win8?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.