Web Devs: "Connection reset" Errors On AT&T 3g, Nowhere Else
We maintain a server-side reporting application for a client. On one reporting page, there are several heavy database call开发者_JS百科s in the middle of the page, causing the page to take 5-10sec to render.
Problem: When accessing the page via an iPad over AT&T 3G, the page successfully loads about 50% of the time. Sometimes, however, Mobile Safari renders the top half of the page and then gives a "Server Connection Was Reset" error.
Background information
- If you switch the iPad from 3G to a solid broadband Wifi connection, the page works 100% of the time
- The page works 100% of the time on my Verizon iPhone over 3G
- The page works 100% of the time over broadband, regardless of device or browser - PC, Mac, phone, iPad, etc.
- The page is not particularly heavy. Total weight of all assets is 108 KB (440 KB uncompressed)
- Even over AT&T 3G, the other pages on the reporting site load correctly 100% of the time.
- Originally, the database calls were taking 10+sec, and the iPad+AT&T 3G problem happened 100% of the time. Some simple optimizations brought the calls down to 5-10sec and now we see it about 50% of the time.
- Server platform is IIS6
- New info In IIS's log files, the "failed" page request (the one that result in "connection reset" errors in Mobile Safari) looks like a normal HTTP request with a result code of 200 (success)
- New info Tentatively, it looks like this problem does not happen in Opera Mini on the iPad. Baffling, since it seems like a AT&T network issue. I say "tentatively" here because we can't rule it out. We currently have an intern refreshing the page on Opera and noting any errors. :)
- New info We did some quick optimizations on that 5-10sec database query. Now the pause is more like 3-5 seconds instead of 5-10 seconds. As a result, the Mobile Safari "connection reset" error now happens more like 10% of the time instead of 50% of the time.
So now I'm not sure what to think. If it's a network issue, why does Opera Mini work and not Mobile Safari given otherwise identical circumstances? But then... if it's a Mobile Safari issue, why does Mobile Safari work fine over a broadband+Wifi connection?
Is Mobile Safari using different timeout settings based on whether it's on broadband or wifi? I don't know if that's a.... thing that it does or not.
To award the bounty points, I guess I'm looking for an answer that specifically addresses one or both of the following questions (1) Does Mobile Safari vary its timeout settings based on the type of the currently active network connection (2) Is there some kind of known specific thing with AT&Ts proxy servers being twitchy and terminating connections that have been idle for a few seconds? Like: "Yes, they will terminate an idle connection after 4.25 seconds"
I think the short answer is that 3G data connections are unreliable. That's partly down to physics -- it just can never be as reliable as a wired connection -- and partly down to games that the carriers play.
Almost all carriers seem to use transparent proxy servers that have varying degrees of brokenness.
I can't say for sure what AT&T are doing, but I can list a few things that I've seen from customers of my app (which accesses a REST web service):
- Truncated parameter strings
- 500 errors on long parameter strings
- Random 503 errors
- Random 403 errors
- A 200 return code with an error returned either in XML or text form (i.e., no way to distinguish between an error from the web service and the proxy without trying to parse the message. Of course, you don't know what the format of the message is)
- Sporadically slow connections
- Partial downloads (without errors)
For a long time I assumed it was a latent bug in my code, but then a tried my app on a handset on Vodafone rather than O2...
Unless you're in a corporate environment and can assume one particular carrier, there's not much you can do other than to make your code more resilient. I've tried to make my code:
- More tolerant of strange or unexpected errors
- Make parameter strings shorter (I don't control the web service so this is hard!)
- "Dial back" the performance if I get too many errors (e.g., request fewer records in each request)
- Try not to force end-users to deal with bizarre errors that they, practically speaking, can do nothing about
I think the last point is the most important one, though it's impossible to do 100% of the time unfortunately.
You should read this article about why you have problems when connecting through AT&T's 3G network.
And about Opera Mini ... Well, Opera uses this proxy-like technique to pass all the data through their own servers, compress it and then send it to you. This results in less traffic from & to your mobile device and thus - faster loading time.
There's not much you can do, other than compressing your output and optimizing everything for speed - even replacing double quotes with single ones (sorry, I'm a PHP coder, don't know if that's the same in ASP) makes sense here. With today's broadband connections - nobody really cares about this, but mobile connectivity isn't that advanced yet and kind of brings us back to the dial-up modems era when it comes to optimization techniques.
I suspect the problem isn't with Safari but with AT&T's 3G routers/proxies. I've had success avoiding similar problems by switching to HTTPS, which seems to prevent buffering by AT&T and has helped avoid spurious connection resets.
My guess is that AT&T is playing games with their network to balance load or prevent other bandwidth issues and that is probably screwing with your particular data for some reason.
I would suggest batching the data retrieval to return a subset of records, and using the continuous scrolling pattern to improve the performance of the page. With continuous scrolling, new items will be loaded as you scroll down the page. I've seen this technique used successfully in similar situations.
Here's an article that explains how to incorporate the continuous scrolling pattern in ASP.NET with JavaScript:
http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=371
And here's another good example that uses jQuery:
http://www.eggheadcafe.com/tutorials/aspnet/b8381915-06d9-4538-b4bb-5ac2a8e73f34/implementing-continuous-scrolling-ui-pattern-in-aspnet.aspx
Hope this helps.
精彩评论