iOS Safari WebSockets : huge latency when sending messages at short intervals - ios

I just found a very annoying thing about using websockets on iOS Safari (iOS 5.0.1). When sending two messages at very close interval (think 30 - 40ms, for example, sending a message at mousedown on a button and one on mouseup) the two messages arrive at 200 to 300ms of interval on the server.
This makes using WebSockets on iOS really painful for making a remote controller for example...
I'm affraid I know the answer, but is there anyway to make it work better ? It seems like it's a bug in the Websockets implementation of Safari but could it also be coming from the WiFi implementation (I hardly think so...) ?

I just found out some kind of workaround, and that the websockets implementation of Safari Mobile behaves even weirder than what I already found out.
While making some ping tests to validate my theory, I realised that I didn't have the problem anymore. Then I tested again with my original code and I had the same problem again.
Then I realised what changed in my code, compared to the ping test : the server never sends anything to the client. So, whenever my server receives a message from the iPhone, he sends a message back to it. That way, the latency disappears. It's really weird and there's probably something to be done to fix that issue, but in the meantime, this will do...

Related

Wink API Subscriptions Stop Sending Overnight

I'm using the Wink API to control lights and thermostats etc. In the API you can subscribe to device topics to receive events such as when a light is turned on or off. This is handled through PubNub. I have this all working except that the events stop being sent if I leave the system overnight.
If I try to "manually" toggle a light by tapping the physical switch then normally an event is fired and received by my application via PubNub. Restarting my application and thus reconnecting to PubNub does NOT resolve the issue. The only way I've found to resolve the issue is to open the Wink app itself. Nothing else needs to be done but to open the Wink app. Then if I manually toggle the switch the event will show up and be received by my application. This solution works even if I don't restart my application.
There appears to be some sort of wake or keep-alive going on. Although I don't see anything in the Wink API docs that state such. There is also nothing sent from PubNub during this downtime. I have logging being sent out for the status(), message(), and presence() callbacks and nothing is logged from these overnight. Therefore taking all the above into account I believe the issue resides on the Wink side of things.
Unfortunately, Wink does not provide developer support. The Wink app is obviously doing something but because the transactions are encrypted it is unknown what it is doing. Also my test cycle is 8 hours long currently so it is difficult to debug this by trial and error. I'm working to see if this "timeout" is shorter than the overnight 8 hours I've experienced so far. i've also tried power cycling my Wink Hub yesterday but that did not resolve the issue.
Anyone else run into this issue? How do you keep subscriptions alive so that they are always sent?

Phonegap IOS slow on app start but only when WIFI is disabled

OK. Here is some additional details about this problem...
The problem is that when you make a jQuery ajax call in iOS, it seems to take forever to return with a 404. The timeout doesn't seem to take as long on Android.
The reason the timeout is the issue is because the ajax call has a success and fail callback, so it takes the length of the timeout to call the fail callback. If your code doesn't progress until either of these callbacks are called then it will appear as if your app has stalled.
I fixed the immediate problem but I still have this issue in other places where I have a loading spinner - so it's not so much of an issue there. However, is there a way to change this timeout value? And should I change it if I can?
I have a Phonegap app running on Android and IOS.
For some reason the initialization on IOS is very slow when WIFI is turned off. However, it acts normally if Airplane mode is turned on (in which case WIFI is off).
It always behaves the same at initialization on Android.
During initialization the app...
Get's the MACAddress using the phonegap plugin.
Get's the connection information using the phonegap plugin.
Does an ajax call using jQuery ajax, it does not wait for the data to return - however.
I've tried debugging the problem but it seems like the app is doing absolutely nothing while it hangs (it takes like a minute+ to initialize as opposed to the usual couple of seconds). There are no error messages or any significant syslog messages. It eventually starts and works normally.
I'm stuck on ideas as to what could be causing this, I know the code works correctly - at least on Android - because I followed it through and I also removed any unused plugins. I was hoping some of you might have some suggestions as to what you think may be the cause.
I'm sorry that I can't share the source because my boss would be upset with me if I did.

Why do I get packet loss when using GKMatchSendDataReliable?

I have a multiplayer iOS game, and I am sending data using GKMatchSendDataReliable. However, occasionally, the data packet is lost. I've checked on the sending end and I am not getting an error. I'm just not receiving it on the receiving in. It is intermittent, and I have NSLogs right at the beginning of my receive method, so I always know when I get a message.
Is GKMatchSendDataReliable 100% reliable? It seems like a waste to have to set up my own reliable data sending routines.
It seems that this only happens when one device is on Verizon's LTE network. I havn't tried any other cellular network. When using Wi-Fi only, not necessarily the same wi-fi, it works fine.
This happens to me too. It appears that while GKMatchSendDataReliable is oodles more reliable than GKMatchSendDataUnreliable (which loses about 2% of packets in my tests), GKMatchSendDataReliable seems to occassionally lose the first packet I send (immediately after connecting).
My users also complain that some data may be accidentally lost during the game. I wrote a test app and figured out that GKMatchSendDataReliable is not really reliable. On weak internet connection (e.g. EDGE) some packets are regularly lost without any error from the Game Center API.
So the only option is to add an extra transport layer for truly reliable delivery.
I wrote a simple lib for this purpose: RoUTP. It saves all sent messages until acknowledgement for each received, resends lost and buffers received messages in case of broken sequence.
In my tests combination "RoUTP + GKMatchSendDataUnreliable" works even beter than "RoUTP + GKMatchSendDataReliable" (and of course better than pure GKMatchSendDataReliable which is not really reliable).
Apple stated that this was a bug and fixed in iOS7

Using Sockets & GameKit at the same time. Drastic socket speed reduction

I've encountered a pretty large issue and have been trying to find a solution for 2 months now with no luck. I've submitted it as a bug, ( https://bugzilla.xamarin.com/show_bug.cgi?id=4910 ) but was hoping maybe someone here could shed some light on the cause of the problem, or suggest a work-around.
In a nutshell, to encounter the error:
Create a basic .Net socket connection between two devices
Create and initialize a GameKit.GKSession object on a least one device.
What occurs is the transfer of the data on the .NET socket becomes erratic and too slow to be usable. I've performed many tests across different devices (see link below) and it affects all of them (iPad 3 affected the least). I've tested it between an iPhone and a Windows PC and it still occurs. MonoTouch's GameKit code is somehow affecting the Socket code.
As you can see from the spreadsheet, speed drop from a few milliseconds to send 1 MB to several minutes to forever.
As soon as the GameKit.GKSession is set to null, any backedlogged data on the socket flows freely again and the sockets act normally once more.
Sample Windows and iOS/MonoTouch Apps demonstrating problem: https://dl.dropbox.com/u/8617393/SocketBug/SocketBug.zip
Test results across different devices (PDF Spreadsheet):
https://dl.dropbox.com/u/8617393/SocketBug/SocketBugTestResults.pdf
This issue seems so hard even Apple decided to circumvent it: http://developer.apple.com/library/ios/#qa/qa1753/_index.html#//apple_ref/doc/uid/DTS40011315
The revealing sentence is this: "This change was made to reduce interference with Wi-Fi."
To assist with anyone that comes across this problem, the issue only manifests itself when the GKSession.Available is set to true. This is required for the device to be discoverable, but not to maintain a connection. With this in mind, a temporary work-around can be used where the GKSession.Available is only set to true when required, and set to false as soon as the connection has been made.
In my scenario, I have a socket connection to the server on both devices. I use this connection to send a message from device A to device B, asking it to become discoverable via bluetooth for the next 10 seconds. As soon as the message is sent, device A begins looking for device B and connects as soon as it finds it. Once the connection is established (or 10 seconds elapses without a connection), device B turns off discoverability and the socket behaves as normal.
In my circumstances, this is an acceptable (pending no real fix) workaround to the problem.

Gamekit Latency

I have the following problem with GKSessions:
Sometimes there is a huge delay when sending data (3-4 seconds sometimes up to 10 seconds) in a client/server application.
If the server sends let's say 10 packets during the delay, those 10 packets are received all at once on the client. The weird thing is that the server still receives packets from the clients during the delay.
This delay seems to be worse in WiFi networks but also happens in bluetooth networks.
Did anyone else encounter such delay spikes when using gamekit?
What could be the source of this issue?
I've been working a lot with gamekit and gksession. I always use the Peer2Peer mode even though some people discourage it. I never experience any kind of delay like the one you describe.
Do you send with GKSendDataReliable or GKSendDataUnreliable? Try switching to the other and see if it changes anything. If you're using GKSendDataReliable then the sending device will wait for a "Received" message from the receiver before sending the next message. This might be the problem.
On your testing devices: Is anything running which might flood the network?
I was testing a multiplayer gamekit based game, and if I had several active devices then suddenly some would stall completely, and I needed to hard reboot (shut down completely and restart) them to make them work again.
If you keep getting in trouble you might want to try a much more low level api: dns-sd https://developer.apple.com/library/mac/#documentation/Networking/Conceptual/dns_discovery_api/Introduction.html
I hope you make it work, good luck!

Resources