Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Issues with close connection and delete connection on Android

Author
Message
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 28th May 2013 18:41
This is all occurring in AppGameKit 10812 under Android 2.3 and 4.2. With the player as well as a built APK.

I'm having some issues with handling failures to connect to a server.
My program needs to be able to check the server for chat messages every few seconds.
If the server is offline I run into a lot of problems with AGK.

First, the commands SetHTTPHost() and SendHTTPRequestAsync() always return 1 with the server up or down.

Next, if I call CloseHTTPConnection() on a connection that was made to a downed server, Android OS hangs for about 60 seconds.

If I call DeleteHTTPConnection() on a connection attempted on a downed server the Android app terminates prematurely without warning.

If I do not close or delete the connection the app runs OK, but my previous encounters with this would also cause hangups when more than a couple of connections were opened. Also it seems to me that just abandoning and leaving a connection open that has not received a response is dangerous and will likely clog the pipeline.





Is this a bug? Windows handles deleting and closing of the failed connection without any issue or delay.
Or am I doing this all wrong?

All help is greatly appreciated!

Debug logs are attached.

Attachments

Login to view attachments
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 28th May 2013 19:17
In your test, you close and delete the connection when your first check doesn't return a value.

I would suggest that you only close the connection when all attempts on the first request have failed.

And, you don't call Sync() in the loop. This might or might not be critical to the AppGameKit engine checking for http processes.

Try this:



Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 28th May 2013 19:28
Interesting! That helps!
Oddly though, my chat client program does include a sync() call every loop.
I'm going to try adding in some more sync() calls closer to the calls to delete and close connection to see if that remedies the issues and I'll report back.

Thanks!!!!

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 28th May 2013 19:44
Does your chat program actively delete and recreate the connection every time it doesn't get the response immediately?

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 28th May 2013 20:42
No my code has delays in it so that it waits a bit before deleting the connection.

I've added an extra delay in my code for my chat program using a repeat loop with sync() immediately before deleting the connection and I'm still crashing.

Oddly, my chat program will close the connection, but it takes about 50 seconds from the start of the close connection call to the end of it.

I isolated my functions for my chat program and they work well standalone, so I've got something else interfering somewhere.
I'll report back if I ever fix it.
Thanks!

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 28th May 2013 20:46
Good luck and Happy Programming!

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 28th May 2013 21:38 Edited at: 28th May 2013 21:43
OK sooo.... super weird issue.
If you replace 0.0.0.0 IP address with an actual IP address, say your own, then this locks up and takes ~60seconds to close a connection.
If it is just that fake IP then all is well.

debug log here:


Modified code here (goes through 5 iteration of new connection attempts, but only 1 is needed):


Super not cool...
Would you mind checking this with your own IP to see if you get the same issue?
With my IP this causes an issue, but only on the Android devices.
Very odd...

Without knowing the inner workings of these AppGameKit commands I can't really understand why this would be an issue. All I know is that if my valid IP address is used, but there is no server to connect to then it is a problem.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 28th May 2013 23:26 Edited at: 30th May 2013 16:30
I had assumed that the '0.0.0.0' that you were posting as the IP address was not the actual one you were using.

I'm surprised that you got it to work at all.

If you are testing locally, the commonly used local ip address is '127.0.0.1'. And you need to have a web server running to provide the page asked for.

And do you actually have a newmessage.php file on your real server at the document root level (the domain without any sub directories)?

Try this code:


You can change the value of i_async to try both request types and switch the two dom$ lines to try IP address versus actual domain name.

I own the domain and have tested that this works in Windows just fine. And it worked fine through the v10812 Player.

If the test above does NOT work for you, then you have a connection issue that has nothing to do with AGK.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 28th May 2013 23:34
I think there's some confusion here.
I'm trying to run tests when the server is actually down.
So the IP is a valid IP, but the Apache server is not running and thus should not be able to get a connection.

So your example won't really help since you have a live server up. Running any of this with alive server is no problem at all. The problem exists when the server is unreachable at the given IP.

If you can try my code and shut down your server application for a minute then you should see the same results. Similarly if you just put in you home's IP address and don't have a server running then you should also see my problem. The whole issue is what to do when the server is down.

Does that make more sense?

Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 28th May 2013 23:44
I've modified the timeout on Android HTTP connections to 6 seconds for the next version
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 00:01
Thanks Paul!! Hope that fixes it.
Does that mean that when you call CloseHTTPConnection that it is waiting X seconds from the time SendHTTPRequest was called or SetHTTPHost? Or is that timeout completely enclosed in the call to close the connection?

My concern is that the Android device will still freeze for those 6 seconds.
Perhaps it is better to just delete the http connection in the case of a response timeout in the app? Or will that leave the connection open?

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th May 2013 00:32
I'm sorry Naphier, I did lose the original point of your problem.

I changed the dom$ to "localhost" (and "127.0.0.1") and turned off my local server and tested. (Opening a browser and entering localhost as the domain verified that it wasn't active.)

It came back pretty quick with both versions of the request and a blank value. No hangs or delays when it closed and deleted the connection.

When I ran it via a Player, it also came back pretty fast without hangs.

But, when I closed the app and the Player got control back (quickly) it had a message saying 'LAST ERROR' and 'Failed to send HTTP request, code: 7'. So clearly the request failed.

It appears that the request made here, while being accepted, has not been completely handled.

I modified the previous test to catch and display the GetHTTPResponseReady value and it did come as -1 to indicate a problem.

But, the SetHTTPHost command should have returned some sort of error because the host connected to was not hosting.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 29th May 2013 00:34
The HTTP call is on a thread, so that thread will wait 6 seconds and then abort. You should wait for GetHTTPResponseReady to return 1 (success) or -1 (failure). If the 6 seconds have passed it will return -1. You can then close the connection without the risk of freezing the app. The reason it was freezing for you is because GetHTTPResponseReady had not yet come up with a response.
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 02:30
Thank you very much, both of you!
This is quite helpful.

@ AL - SetHTTPHost always returns a 1. It would be handy if it returned an error (0 or -1) but I've yet to see that.
Quote: "It came back pretty quick with both versions of the request and a blank value. No hangs or delays when it closed and deleted the connection.

When I ran it via a Player, it also came back pretty fast without hangs.

But, when I closed the app and the Player got control back (quickly) it had a message saying 'LAST ERROR' and 'Failed to send HTTP request, code: 7'. So clearly the request failed."

Interesting that you don't get hangups... mine are consistently 60 seconds from the time of calling CloseHTTPConnection to the next line. I also get the error code 7.

So basically I should be waiting until GetHTTPResponseReady returns 1 or -1 and not relying on my own timeout code. That's kind of good, but I'm a bit of a control freak and would much rather have control over that timeout setting.
If I just delete the connection is it effectively the same?
I'm not real clear on the difference. Would you be able to elaborate for me?

Thanks again for all the help.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th May 2013 03:38 Edited at: 29th May 2013 03:39
Quote: "SetHTTPHost always returns a 1."

Yup, I know that. That is why I put in the request (issue #365). Because that is not a valid response if the server is not serving or can't be found.

In my current WIP (Tier 2), it checks GetHTTPResponseReady AND elapsed time for a timeout condition.

Now I need to go and update it so that it makes sure that it is getting using the -1 if it gets it.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 04:56
Quote: "I changed the dom$ to "localhost" (and "127.0.0.1") and turned off my local server and tested. (Opening a browser and entering localhost as the domain verified that it wasn't active.)"


I'm thinking this is why it came back quickly with no hangups.

I just confirmed this. If I use localhost then there's no hangups, but if I use my actual IP address then it hangs for 60 seconds when I try to close the connection.

So is this 60 seconds the timeout for the http connection thread in AppGameKit?

If I enter localhost into my browser I notice that I get an "oops" message from the browser much faster than if I enter my IP address.

It should also be noted that it takes over 180 seconds to close a connection like this on my HTC dinc2 (Android 2.3).

I'm going to work on some more testing tomorrow to see if I can get something acceptable using the -1 return from GetResponseReady. It seems to me that using any timeout in my program that causes a premature closing of the connection may cause a hangup like this, so I may have to avoid it.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th May 2013 16:27
Okay, so I switched to using the actual IP address for my computer (I have static IPs on all my home computers) and it still was very fast on the disconnect when the Apache server was down.

So I tried an IP address that didn't exist. The display showed that it took about 15 seconds in Windows and about 10 in the Player before GetHTTPResponseReady gave up and returned -1.

But once it did that, the disconnect and delete were instantaneous.

What you are probably seeing is not a time lag when disconnecting but when it is waiting for GetHTTPResponseReady to return something.

The code I posted shows that the delay is waiting for GetHTTPResponseReady.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 16:40
Just wanted to run through some tests for some empirical data this morning. Using localhost as the IP results in near instantaneous return of -1 from GetHTTPResponseReady() and using the actual external IP results in a MUCH longer wait for the -1 return. Here is the data:

Time of connection creation to return of -1 by GetHTTPResponseReady

Connection to actual IP where no server program is running

Nexus 7 (Android 4.2)
63394
63377

HTC dinc2 (Android 2.3)
189580
189558

Connection to LOCALHOST where no server is running

Nexus 7 (Android 4.2)
520
513

HTC dinc2 (Android 2.3)
503
509

It should be noted that there was a programmed 500ms delay between connection creation and checking the response ready. So localhost results in -1 in really no time flat.



@AL - you ninja'd me

The difference in results baffle me and I wonder what the reason is.
I'm not on a static IP from my ISP, but my public IP hasn't changed ever (6+ months since we moved).
Internally all of my machines have a fixed/manually assigned IP.
I imagine the slow response is either due to my ISP (Brighthouse/Timewarner) or my router (cheap old Netgear WND3300).
But when the server is up the replies are instantaneous even to people not on the same network (though we've always used the public IP anyway so that shouldn't make a difference).
Would you mind shooting me a personal email so I can send you my public IP? I'd be very appreciative if you could test my IP from your devices.

My curiosity is probably getting the best of me at this point!

JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 29th May 2013 16:57
None of this is really surprising. Your ISP servers will have their own connection time-out before responding with success or failure. Take into account also packet-switching delays on the route. Internet connections can never be as fast as using localhost, because there may be potentially hundreds of intermediate steps.

Networking is inherently fraught with potential disaster. I deal with it every day on quite complex multi-user systems.

*You* should decide what is as an acceptable time period for a valid response (which could report good or bad) and if it's an asynchronous call you must be prepared to throw away the response if it arrives after you have aborted with a "Couldn't connect!" error message.

-- Jim DO IT FASTER, EASIER AND BETTER WITH AppGameKit FOR PASCAL
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th May 2013 16:57
I started to send an email using the link on this page. But it popped up with 'NaplandGamse@gmail.com'. That looks like a typo.

I have just enabled the email link for this forum. Once you send me your message, I will disable it again (I don't want lots of unsolicited emails, which I do get).

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 17:11
Oops! Email sent. Thanks AL


@Jim
Quote: "*You* should decide what is as an acceptable time period for a valid response (which could report good or bad) and if it's an asynchronous call you must be prepared to throw away the response if it arrives after you have aborted with a "Couldn't connect!" error message."


That's a good point, but there's some dangers with using AppGameKit and this method.
AGK seems to only be able to handle one open connection on Android. So if you start a connection, it fails to respond in your programmed timeout, you ignore it and wait to close it until the response ready returns -1... If you start a new connection before the other is closed then AppGameKit locks up.
Also if you're sending data to a server and the data from your first attempt is sent after your second attempt has started then you've got duplication on your server.
And if you try to close/delete the connection before AGK's internal timeout is up then you lock the program and have to wait anyway. Sort of a catch 22.

I do wish that we could manually set the command's timeout vs. AppGameKit having a set timeout to the commands.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th May 2013 17:24 Edited at: 30th May 2013 16:31
Okay. I tested with your IP and page.

And I am assuming that your server is currently down.

On Windows it took 21 seconds for GetHTTPResponseReady to finally return -1. On the Android Player it took 63 seconds.

This is the code I used to test (with your IP address set to x's for the purpose of this posting):


EDIT: I just tested using the non-asynchronous call and got the same timing results.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 17:28
Cool thanks. Yes the server is down.
That seems consistent with my results. I'm assuming you're using Android 4.2. I find it strange that Android 2.3 took so much longer. I hope that Paul's update will help to address that because no one is going to keep an unresponsive app open for 3 minutes and if they try to close the app it will freeze up...
Wait and hope...

Thanks again for all the help, my curiosity is mostly satisfied now!

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th May 2013 17:38
Yes, my device is 4.2.

I am expecting delivery of Android 2.3 and 3.2 devices soon. I found a couple relatively cheaply on eBay.

I can repeat my tests then.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 17:39
Cool! Thanks. I'm curious to know what the delay is on a 3.2 device. Also iOS...
Ugh here goes my curiosity again!

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th May 2013 17:55
On my iOS 6.1.3 iPad 2, the time was 60 seconds. The time was the same on my iOS 6.1.3 iPod Touch.

When I closed the app and it returned to the Player, the error message was "http://x.x.x.x/newmessage.php closed unexpectedly"

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 29th May 2013 18:00
Good to know. Thanks again!

Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 30th May 2013 17:29 Edited at: 30th May 2013 17:34
Quote: "The difference in results baffle me and I wonder what the reason is. "


I suspect it is down to the TCP/IP stack on each device, if a connection attempt is ignored instead of refused (explained later) then the stack assumes the packet was lost on the way, waits some time and tries again, if it still doesn't hear anything it waits a little longer and tries again. After it has tried a certain number of times it gives up which is why TCP/IP connections can take minutes to timeout because it has a set procedure it follows when it thinks packets are getting lost. From your results it looks like different devices or OS versions have their own retry procedure so that the timeouts vary significantly.

The reason a receiver would ignore a connection instead of sending back a connection refused, and letting the sender know instantly that the connection will fail, is for security. If it is ignored the sender doesn't know if the receiver exists unless they manage to find an open port, and the TCP/IP timeout length makes port scanning a longer process.

The new method I'm using to timeout the HTTP connection is to abort the TCP connection after a certain number of seconds of no connection. I've also applied this to iOS and Windows so the max time AppGameKit will wait is 6 seconds on any platform.
Naphier
13
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 30th May 2013 17:32
That's a great explanation! Thanks for helping out with this.

Login to post a reply

Server time is: 2024-05-04 12:10:07
Your offset time is: 2024-05-04 12:10:07