Bug 1330 - WebService failure on AT&T, Ok Verizon and WIFI
Summary: WebService failure on AT&T, Ok Verizon and WIFI
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 4.x
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-10-06 22:20 UTC by Mark H
Modified: 2013-02-11 22:12 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Comment 1 Jeffrey Stedfast 2011-10-07 14:28:11 UTC
Hi Mark, I've poked a developer who is more familiar with Mono's WebService implementation and he thinks this likely has nothing to do with Mono and is probably just a flaky AT&T wireless network issue.

I guess that makes sense to me since this only seems to be a problem on AT&T's data network (works on Verizon and WiFi as you noted).

At this point I'm not sure what to suggest. I want to help but I don't know where else to go from here.

Do you think that could be the issue as well?
Comment 2 Mark H 2011-10-07 14:34:27 UTC
Jeff:
No don’t think so I have users in Pennsylvania, Seattle and Minnesota. All able to recreate the issue. If you use my test program on an AT&T provisioned device and follow the above sequence you can recreate. I am able to recreate scenario every time from multiple states myself.
Comment 3 Jeffrey Stedfast 2011-10-07 14:37:38 UTC
Okay, Gonzalo just corrected me - I had misunderstood his explanation. He only meant that it wasn't a bug in System.Net and that it could be a MonoTouch issue.

Sorry about that.
Comment 4 Mark H 2011-10-07 14:48:12 UTC
Thanks Jeff:
Just to note the test program is just implements a simple web service call that demonstrates a trap-able error. In my production code when I call the "CreateDB" service call I often get booted out of the program with no crash log and I cannot even try/catch the error. In both cases (Simple and CreateDb call)  WireShark on server when it hits error never receives a request.

      this.InvokeAsync("CreateDB", new object[] {
                    psUser,
                    psDBType,
                    psFileType}, this.CreateDBOperationCompleted, userState);

Tried putting try/catch and it never hits the catch, doesn’t even give a crash
log, program just ends.

Thanks
Comment 5 Jeffrey Stedfast 2011-10-07 15:08:27 UTC
Hi Mark

I thought I remembered you saying something about a crash!

Okay, so... the reason that the try/catch is not working when wrapped around InvokeAsync is because InvokeAsync is starting up a new thread where the operation will be run, so the exception is not actually being thrown while inside that try/catch block.

Unfortunately, CreateDB is an auto-generated method so, while you *could* manually modify it to do exception handling, it would just get overwritten if anything caused that file to be auto-generated again.

The simplest solution I can offer is to set your own unhandled exception handler on the AppDomain:

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

I'm not familiar at all with WebService stuff, but perhaps there's a better way of catching those exceptions.

I wonder if perhaps a good way might be to spawn your own thread with a synchronous call to CreateDB?

I'll have to try and get my hands on an AT&T enabled device (my iPad is wifi only) or poke one of the other devs to take a look at this.
Comment 6 Jeffrey Stedfast 2011-10-07 15:12:39 UTC
doh, n/m about that last suggestion. The InvokeAsync is not being called manually by you, it's called in the auto-generated code. Duh.
Comment 7 Mark H 2011-10-07 15:19:01 UTC
Thanks:
The CreateDb is an occasional use, Once at startup and then when they have corruption or feel need to Download a new DB. I'll try spawning new thread for this one. The other service calls similar to the test case, are called frequently and its more bothersome as they receive an error and have to retry. Sometimes error occurring in middle of a longer process as there are two or three service calls in the transaction. Again its wierd cause the Verizon guys are smooth sailing.
Comment 8 Mark H 2011-10-07 15:23:18 UTC
Right now I have a clunky stop gap in for CreateDb that if I detect Cellular messagebox to say it is advisable for large downloads and to switch to WIFI for these. Its the other frequent WebService calls that are driving the users crazy.
Comment 9 Jeffrey Stedfast 2011-10-07 15:23:40 UTC
Miguel just reminded me of something that I debugged months ago and completely spaced on.

It might just be that the data connection needs to be woken up, which can be done by making a call to MonoTouch.ObjCRuntime.Runtime.StartWWAN(Uri)

You should use the http or https Uri that your service is on - StartWWAN() will make a connection to your web server using the iPhone's native networking library (Mono's WebService API is written using the BSD socket API).

If this works for you, I'll see what I can do about fixing the WebService APIs to invoke StartWWAN() before trying to connect to remote services.
Comment 10 Mark H 2011-10-07 16:12:25 UTC
Thanks,
I will give this a shot and let you know.
Comment 11 Jeffrey Stedfast 2011-10-07 16:15:37 UTC
Did some more digging and it looks like WebServices already uses the same APIs as WebRequest which already calls StartWWAN() in WebConnection.Connect() so the StartWWAN() suggestion may or may not work.

Thinking about this some more, all I can think of is that maybe the WebConnection is connecting the first time ok (e.g. when the GSM antenna is awake) and then the CreateDB command is being issued after the antenna has gone to sleep?

*If* that is the case, that might explain why it's not working even though it all goes through WebRequest.

A possible solution to this might be to try overriding the GetWebRequest() method

protected override System.Net.WebRequest GetWebRequest(System.Uri Uri)
{
    WebRequest req = base.GetWebRequest(Uri);
    ((HttpWebRequest) req).Connection = "close";
    return req;
}

This would make the http web connection not use HTTP/1.1's keepalive feature, so if the StartWWAN() solution works for you, then it's probably better than doing this because it would force a new connection for every WebService command.
Comment 12 Mark H 2011-10-09 22:37:49 UTC
Jeffrey:
Tried Invoke of StartWan that gave same bad results.
Tried override above but that throws a compile errorof no suitable method found to override. 
Whats next?
Comment 13 Jeffrey Stedfast 2011-10-10 12:22:31 UTC
You want to override GetWebRequest() in Service1.cs

(Obviously this is not ideal for long-term since Service1.cs is autogenerated, but should suffice long enough to track down the issue).
Comment 14 Mark H 2011-10-10 16:13:59 UTC
Oh Sorry.
Tried that and when app calls webservice, all I get is catch error that says "Keep-Alive and Close may not be set with this property.
Comment 15 Jeffrey Stedfast 2011-10-10 16:18:34 UTC
Sorry about that, I was wrong about ((HttpWebRequest) req).Connection = "close";

I think it should be ((HttpWebRequest) req).KeepAlive = false;
Comment 16 Mark H 2011-10-10 16:36:09 UTC
Jeffrey:
Thanks, Looks like that fixes issue in my Test App for the one service call I coded for. I'm going to try and move code to live app and try all service calls. I'll let you know.
Comment 17 Mark H 2011-10-11 10:42:53 UTC
Jeffrey:
This Override fix seems to have done the trick. Go a couple of errors in testing but all were caught and program was not killed like before the override. Thank you for great support!
Comment 18 Jeffrey Stedfast 2011-10-11 10:54:50 UTC
well, we still need to figure out the root cause, but this narrows it down quite a lot and it at least allows you to continue work and get a temporary fix out to your customers :-)

I'm guessing the problem is that the initial connection is being made via the data connection, the radio is falling back to sleep (after some non-use) and then some code or other in System.Net is trying to re-use the connection, which is failing, and an exception (or not?) is being thrown but higher level code (ours, not yours) is failing to properly handle it.

Will continue to dig into this...
Comment 19 Miguel de Icaza [MSFT] 2013-02-11 22:12:40 UTC
Closing