AMANZATECH / apns-sharp

Automatically exported from code.google.com/p/apns-sharp
0 stars 0 forks source link

Feedback service glitches once a while #35

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Running the feedback service right after sending out the push notifications

2. The feedback service works fine most of the time, but will get stuck once a 
while (like once every 30 or 40 times), at the line:

apnsStrean.AuthenticateAsClient(Host, certificates, 
System.Security.Authentication.Sslprotocols.Ss13, false);

in the ensureConnected() method of class FeedbackService.

3. It will stuck at that line for 5 to 10 minutes and then throw an IOException 
which always says:

An existing connection was forcibly closed by the remote host...

After that, it comes back to work again. 

What version of the product are you using? On what operating system?

I am using the latest version of the apns-sharp code running on Windows xp sp3 
with visual studio 2010.

Please provide any additional information below.

The thing that confuses me most is that why does the 
apnsStream.AuthenticateAsClient() line work most of the time and suddenly stop 
working for a bit, and why does it take so much time to throw an exception? I 
guess there's something I don't understand here. This has driven me nuts, 
please point me out some directions. Thank you so much!!!

Original issue reported on code.google.com by sterling.li@gmail.com on 15 Jun 2010 at 1:14

GoogleCodeExporter commented 8 years ago
To be accurate, the IOException says:

Unable to read data from the transport connection: An existing connection was 
forcibly closed by the remote host.

Original comment by sterling.li@gmail.com on 15 Jun 2010 at 1:28

GoogleCodeExporter commented 8 years ago
I'm not sure where to go with this one.  I've never seen this myself, and 
there's nowhere I'm aware of that the timeout can be set on that method call.  

Can you try some testing with the apnsStream.ReadTimeout and 
apnsStream.WriteTimeout ?  Try setting them to an appropriately low value and 
see if that causes the exception to arise a bit more quickly.

Original comment by jond...@gmail.com on 21 Jun 2010 at 4:13

GoogleCodeExporter commented 8 years ago
Hi,

I am experiencing the same issue. Here are more details about the environment: 
I have installed a service that uses that library on a Widnows 2003 Server RC. 
I have not really been able to pinpoint when and why it occures but it happened 
on some notifications and some devices. To be more accurate some notifications 
can get to a device but the same notification may not be able to get to another 
one.

Here are some more technical details: the error that is occuring is a service 
error (the event <myServicename>.OnError is raised)

/* CODE STARTING */
service.Error += new NotificationService.OnError(service_Error);
/******************/

I have intercepted that error to write a log into the server's event viewer :

/* CODE STARTING */
static void service_Error(object sender, Exception ex)
{
       EventLog.WriteEntry("My Notifier Service - Error", String.Concat("Error: ", ex.Message, 
                                                                               "\n\rInner exception: ", ex.InnerException,
                                                                               "\n\rSource:", ex.Source,
                                                                               "\n\rStack:", ex.StackTrace, 
                                                                               "\n\rTargetSite (method):", 
                                                                               ex.TargetSite), EventLogEntryType.Error);
}
/******************/

Here is the log in the event viewer when the errror occures :

/* LOG STARTING */
Error: Unable to write data to the transport connection: An existing connection 
was forcibly closed by the remote host.

Inner exception: System.Net.Sockets.SocketException: An existing connection was 
forcibly closed by the remote host
   at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)

Source:System

Stack:   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, 
Int32 size)
   at System.Net.Security._SslStream.StartWriting(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security._SslStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.Write(Byte[] buffer)
   at JdSoft.Apple.Apns.Notifications.NotificationConnection.workerMethod()

TargetSite (method):Void Write(Byte[], Int32, Int32)
/****************/

Looking at the code file NotificationConnection.cs it looks like the error 
occures in the method workerMethod() at the line apnsStream.Write(buffer); . 
That code is protected by a try catch and it is here that the error is raised. 
It explains why we do not receive a notification faiulure (that code should be 
reached later in the function but it stops at the below try catch).

/* CODE STARTING */
try
{
    //Send the notification
    apnsStream.Write(buffer);
    sent = true; //Can only assume it worked at this point
}
catch (Exception ex)
{
    if (this.Error != null)
    this.Error(this, ex);
}
/******************/

If you need anymore information or anymore tests you can contact me on msn 
khazrak@hotmail.com . Can't wait to here from you...

Thank you,
Vivien FRANCOIS - http://www.vivienfrancois.fr/

Original comment by frv...@gmail.com on 21 Jun 2010 at 8:45

GoogleCodeExporter commented 8 years ago
@frvivi your issue is not identical.  You're having problems with the .Write in 
your NotificationConnection.

Your network connection is being closed for some reason.  One possibility is 
you are sending invalid notification data (eg: invalid device token).  Hard to 
say.  Does this happen on every notification for you?

It's pretty tough to diagnose this socketexception from my end.  You're going 
to have to do some deeper digging to see if it's some other network issue on 
your server, or if you're sending bad notifications.

Original comment by jond...@gmail.com on 22 Jun 2010 at 12:54

GoogleCodeExporter commented 8 years ago
Hi jondick,

Thank you for the answer. It does not happen on every notification, it seems to 
be "random". Their should be another error for device token no ? (I log this 
error and it does not happen, not according to logs)

So according to you it is a connection that is closed during the Write method ?

Original comment by frv...@gmail.com on 22 Jun 2010 at 6:09

GoogleCodeExporter commented 8 years ago
Well the problem is,  we don't necessarily no for sure that it's a bad device 
token, we can only guess. 

Apple will close the connection on a bad device token, without any indication 
other than the closed connection, which we don't know for sure if it's a bad 
device token, or if the connection was lost due to other networking issues.  So 
I hesitate to call all dropped connections a bad device token.

Make sense?

Original comment by jond...@gmail.com on 22 Jun 2010 at 6:14

GoogleCodeExporter commented 8 years ago
Yes indeed, it does make sense. What I meant is that their is this event that 
can be raised when the service encounters a bad device token :

/* CODE STARTING */
service.BadDeviceToken += new 
NotificationService.OnBadDeviceToken(service_BadDeviceToken);

[...]

static void service_BadDeviceToken(object sender, BadDeviceTokenException ex)
{
       EventLog.WriteEntry("My Notifier Service - Wrong device token", String.Concat("Wrong device token: ", ex.Message), EventLogEntryType.Error);
#endif

/******************/

So I thought in case their is a bad device token that log would have been 
created but it does not. So I will keep on investiguating that issue and verify 
if a bad device token can generate this. I will get back to you with the 
results.

Note: sorry if the subject of the post has derived, at the beginning I thought 
the issue we had was the same ;)

Best regards,
Vivien FRANCOIS

Original comment by frv...@gmail.com on 22 Jun 2010 at 8:14

GoogleCodeExporter commented 8 years ago
Sorry this event may be a bit deceiving...  It's really only fired if you try 
using a device token that is obviously incorrect (eg: wrong # of characters).

I had originally thought about trying to detect when apple drops the connection 
right after sending a device token, and possibly assuming that was a bad device 
token, but at the end of the day, we just don't know for sure whether a 
connection dropped at that point means it's a bad device token.  So, I'd rather 
have 0 false positives and error on the side of all dropped connections being 
just dropped connections. 

Now, one other approach I could take a look at is detecting multiple 
disconnects for the same notification, and assuming a bad device token if that 
is the case.  By default, the code will try sending the same notification 
multiple times (this is configurable of course), and eventually it will give 
up.  So, let's say you set it to try sending the notification 5 times, if after 
3 times, the message still isn't sent, and 3 disconnects are detected in that 
window of time, it's pretty safe to assume a bad device token (since we can 
check other problems with the notification before hand such as length of 
notification payload). I guess the trick to doing this would be to maintain all 
the various thresholds as configurable values... Maybe as simple as an 
additional property called BadDeviceTokenDisconnectionThreshold or something.  

I'll give this some thought, but I don't think it's a really big issue, 
especially if you're checking the Feedback service regularly (say every hour or 
few hours).  You really shouldn't end up with a lot of bad device tokens in 
normal operation.

One common cause for this behaviour is if you try and use sandbox/development 
device tokens against the production/adhoc/appstore push servers (and vice 
versa).  So, make sure you're not doing that and you should see most issues 
related to this go away.

Original comment by jond...@gmail.com on 22 Jun 2010 at 9:36

GoogleCodeExporter commented 8 years ago
Hi jondick,

I added 

apnsStream.WriteTimeout = 5000;
apnsStream.ReadTimeout = 5000;

in front of the AuthenticateAsClient() line and it solved the problem. Before 
trying this, I used a timer to force the connection to close if when it got 
stuck for a while, and it worked too. However, I still don't understand what 
happened in there to cause this problem. This scenario happens when I kept 
sending a lot of notifications, so it's strange that I am the only one that has 
met this problem, or I guess there is something that I don't know of (which is 
probably the case...). But anyway, thanks a lot man!

Sterling

Original comment by sterling.li@gmail.com on 23 Jun 2010 at 2:55

GoogleCodeExporter commented 8 years ago
@sterling.li maybe I'll add those timeouts to the code too so others don't run 
into this issue... Could be network related issue, hard to say, but as long as 
the timeout is low enough it should keep things running smoothly enough

Original comment by jond...@gmail.com on 23 Jun 2010 at 3:16

GoogleCodeExporter commented 8 years ago
Hello All,
I created push notification successfully, but about the feedback I'm not able 
to understand it?
- when I'll get a feedback?
- how to test feedback?
- I tried JdSoft.Apple.Apns.Feedback.Test but I'm not getting any thing?
- why service.Dispose() is in Main()? is this ok? I think it should be in 
.OnError or .OnFeedback event?
- I have 3 iPhone for testing this, I deleted the app from one of them then I 
send a notification and it was ok for the other 2 but still no feedback?

Can any one create a sample project that have all features tested on it?

and what about JdSoft.Apple.AppStore what is that? and why the test project is 
not complete (in JdSoft.Apple.AppStore.Test there is event buttonOk_Click but 
there is no button with id buttonOk)? 

Regards,

Original comment by maowi...@gmail.com on 5 Jul 2011 at 1:44