Receive Android GCM messages so slow? - android

Google Cloud Messaging (Push message) problem.
I have two smartphones(HTC Sensation XE, Desire HD) and a tablet(Samsung Galaxy Note 10.1 Wifi).
Sometimes I need to wait for almost 15 minutes to receive the GCM push messages. Sometimes I receive the GCM push messages immediately(within 30 secs).
Is it normal? Or just because I'm under Wifi connected?
If it is normal, are there any other services like "long-polling" I can use for retrieving messages from server?
I'm currently using GCM+Polling(AlarmManager) to retrieve messages from remote server.
Any suggestions or better ideas?
Below is my test result:
The left side is server send time, while the right side is client mobile receive time.
All the test results are under Wifi connected environment.
==========================
HD
23:10:18, 23:24:XX
XE
23:11:21, 23:22:44
Note
23:10:20, 23:14:54
==========================
HD
00:08:12, 00:08:27
XE
00:07:55, 00:07:58
Note
00:08:04, 00:13:35
==========================
HD
00:40:21, 00:55:22
XE
00:39:56, 00:40:14
Note
00:40:13, 00:40:59
Thanks!!

GCM uses throttling when there's excessive use, see the following document for more details:
http://developer.android.com/google/gcm/adv.html#throttling

Please read my answer here:
Google Cloud Messaging - messages either received instantly or with long delay
It's basically a tcp timeout problem

You can manually trigger the heartbeat to keep the connection alive by the following code. Some network routers will automatically kill the idle socket connections if it is idle for a particular time period (sometimes 5 minutes). Execute the code in every 5 minute so that the connection will be re-established if it is closed. But, obviously reducing the interval will consume bit more battery (I don't know how much it is relevant here because nowadays the smart phones come up with high mAh battery).
getApplicationContext().sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT"));
getApplicationContext().sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT"));

Related

Movesense - Sensor disconnects after 35 seconds

We have developed an application with Movesense. The application connects and subscribes to the Accelerometers.
It is running for 35 seconds and receives data from the sensor.
Each time after 35 seconds the sensor stops sending data (Not sending onNotification(String data)) and after a few more seconds disconnects. Few more seconds later it reconnects and continues to send data.
This totally ruins the user experience and the ability to work with Movesense.
We have tried 4 different Movesense sensors. The problem exists in all.
Also we updated firmware to all our sensors, but the problem did not go away.
In the Device Documentation in the file "Changes.md" we found the following 2 lines:
"Known Bugs:"
"HR stops sending data after Acc/Magn/Gyro subscription"
Reading trough most of the device-lib documentation, and the issues in Stuck-overflow (i.e. here) we were not able to find any further documentation about this issue.
We have a few obvious questions:
1. Is what we see is the "Known Bug"?
2. If yes, is there any further documentation on it?
3. If yes, is there a known workaround for it?
4. If no, what would you recommend to do?
Thanks,
Eric.
Update: After testing with mobile devices with API 23 or higher the problem disappeared. The original mobile device was API 22. Also, since we don't have another device with API 22 or lower, we cannot rule-out that the API 22 device has some issue in its Bluetooth which may not be related to the API.
I am leaving this question unanswered since we would still like to ask how or where to find more details about the known bug “HR stops sending data after Acc/Magn/Gyro subscription” described by this sentence in the Movesense Device Lib documentation.
Thanks,
Eric.

Pubnub+Python SDK on an Ubuntu Azure-hosted machine. Connection problems

I am experiencing a bad behavior of Pubnub in the following scenario:
Pubnub SDK for Python as a subscriber
Python 3+Django on Ubuntu 14.04
Ubuntu machine hosted on Azure
Android Pubnub client as a publisher
It seems to be that, at a certain point, the Pubnub connection on the server side becomes stale, that is, any message sent from the client is not received by the subscriber.
I have noticed that there are some errors on the log related to pubnub connection:
WARNING 2015-09-30 17:21:24,778 connectionpool 26551 139638563919616 Retrying (Retry(total=0, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError("HTTPConnectionPool(host='pubsub.pubnub.com', port=80): Read timed out. (read timeout=320)",)': /subscribe/.../.../0/...?uuid=...&auth=...&pnsdk=PubNub-Python/3.7.3
After about 5 minutes, the message is received and correctly processed.
I guess that the root of the problem lays in the way Azure manages long http connections, as:
The problem does not arise on my local machine, which has the very same OS version and the same stack
There is an obscure 'azure' parameter in the Python SDK. I tried to activate it without any noticeable difference
As a test I added two more subscribers on my pc and they both receive messages instaneously
Thanks.
It seems to be that the root cause is the fact that Azure cuts HTTP connections above 4 minutes (https://azure.microsoft.com/it-it/blog/new-configurable-idle-timeout-for-azure-load-balancer/).
On the other hand, though, Pubnub creates connections with 5 minutes timeout (320 seconds, see https://github.com/pubnub/python/blob/master/pubnub.py#L1881).
Unfortunately, the Pubnub 320 seconds timeout can not be changed, whereas the Azure timeout seems to be modifiable only via Powershell scripts (uncomfortable, especially if you do not have a Microsoft Window machine).
All in all, I changed the Pubnub source code with a 120 seconds timeout and now everything is going pretty well.
It would be advisable to:
Document that on Pubnub side
Modify Pubnub so that the 320 seconds timeout can be changed
Improve the Azure interface in order to change the timeout parameter without using Powershell
If there is anything that can be done from the PubNub SDK, look at this:
Azure flag on init
https://github.com/pubnub/python/blob/master/pubnub.py#L2112
https://github.com/pubnub/python/blob/master/pubnub.py#L2141-L2146
Linux platform
And this should be getting called if Azure is running on linux:
- https://github.com/pubnub/python/blob/master/pubnub.py#L69-L77
Let me know if that helps any.

How to start a method in the same time on 2 devices

I have 2 android phones phones, both connected to the same wifi, both with bluetooth.
I want some method that syncs somehow the phones and starts a function on the same time on both phones.
For example playing a song at the same time.
I already tried with bluetooth but its with lag, sometimes 0.5 secs. I want something in +- 0.01sec if possible.
Someone suggesting playing it in the future with 2-3 seconds, sending the time-stamp, but how do you sync the internal clocks of the devices then ?
Before calling that particular method, try to measure the latency between the two devices:
1.First device says Hi(store the current time)
2.Second device receives the Hi.
3.Second device says back Hi !!
4.First device receives the Hi.((storedTime - currentTime) / 2 )
Now you have the latency, send your request to second device to start your particular method and start it on first one after the latency.
Try to measure the latency 5 to 10 times to be more accurate.
you have a way to transfer data between the devices right ?
if so you can send a time-stamp which is in the future,
ex: if the present time stamp is 1421242326 you send 1421242329 or something and start the function at that time on both devices.
Basically use #Dula's suggestion (device 1 sends command to device 2 and gives a "start time" which lies in the future). Both devices then start the action at the same time (in the future).
To make sure that the devices are synchronized, you can use a server-based time sync (assuming that both devices have Internet access). To do this, each device contacts the same server (using NTP, or HTTP-based NTP, or contacts a known HTTP server, like www.google.com and uses the value in the "Date" header of the HTTP response). The "server-date" is compared to the system clock on the device, and the difference is the "time-offset from server-time". The time-offsets can be used to synchronize on the "server-time", which is then used as the time base for the actual action (playing the media, etc.).
If your WiFi router allows clients to talk to each other (many public hotspots disable this), you could implement a simple socket listener on one (or each) device and have the initiating device broadcast a message.
For more complicated things and network flexibility, I've had good success with connected sessions using AllJoin. There is a bit of a learning curve to do interesting things, but the simple stuff is pretty easy once you understand the architecture.
Use a server to provide a synchronous event to just the two clients who have decclared their mutual affinity (random as a parm and pair serializer Partner-1 or Partner-2 which they share prior to their respectve calls for the sync event).
Assume both clients on same subnet (packets from 2 events serialized on the server , arrive across the network at the 2 clients simultaneously client-side) This provides synchronous PLays by 2 , bound clients.
The event delivered by server is either a confirm to play queued selected track OR a broadcast( decoupled, more formal)
The only tricky thing is the server side algorythm implementing this:
Queue a pair of requests or error
Part1, part2 with same Random value constitute valid pair if both received before either times out.
On a valid pair schedule both to the same future event in their respective , committed responses.
OnSchedule do the actual IO for 2 paired requests. Respective packets will arrive back at respective clients at same time, each response having been subject to equal network latency
Ng if two diff carrier 4G or lte networks involved. (Oops)
This thing is possible via socket, you will send a event via socket then the other device receive that event. For learn socket io chat
maybe it's not the answer you are looking for but i think that due to the high precision you are wanting , you should look for a push technology, i advice you to take look at SignalR. It's real time technology which gives you abstraction of sending methods , it have a built-in methods like Clients.All.Broadcast that fit your needs.
You can try to use some MQTT framework to send message between two device, or into a set with more number of devices.

Google GCM delay, TCP timeout fix?

I have an application which depends on sending instant messages. I use google CSS and XMPP to achieve a persistent connection to the GCM server which works well.
But sometimes there is a delay while receiving the messages (10-15 seconds) on the client side (when on 3G), and I need to find a fix. I was reading that TCP connection timeout can occur while mobile operators often kill connection sockets, so I was thinking if there is a way to have a persistent connection with the GCM server on the client side as well?? Or could pinging the server be helpful?
I would be really grateful for any suggestion.
In order to be a battery efficient service , GCM in order to prevent TCP timeout sends a heartbeat every 18 mins on a 3G mobile device and 28 mins on Wifi . That is the reason why messages are delayed . Well one way to fix it is to send that heartbeat every X minutes . Just put the following code in a timer inside a service .
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.e("Trying to save", "GCM or FCM");
getApplicationContext().sendBroadcast(new Intent("com.google.android.intent.action.c"));
getApplicationContext().sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT"));
}
}, 0, 138000{Set this time interval as per your needs;Preferably 5 mins});
CAUTION: Reducing the time interval may result in draining of device battery so
chose that wisely.
This will keep on reviving your connection to GCM servers and you will recieve notifications on time. Good Luck , let me know if it worked

Android Socket High CPU usage

I did a client/server(android/pc) and it seems that network usage from client uses a lot of CPU. Like to receive only 4k-5k from network, the cpu rises to 33 milliseconds. The cpu can be higher than 90-100 milliseconds if data is higher like ~32k.
First, I've tried the client(network part) in java version and after in c and the problem is still there.
I profiled the server part that send data and it uses about 0 millisecond.
Some details:
TCP connection.
The client connects to the server, client sends request, server sends
data (chunk of 4-10k), client send request, server sends...
Network part is threaded.
Get data with (recv or recv/select).
Smart Phone: Nexus one.
Tested in profiler mode (only network part and display fps/milliseconds).
Tested in Wifi (computer, phone, network are close).
Let me know if you have any suggestions or questions.
Thanks.
Are you using BufferedOutputStream on Android side to write the data? If not, it writes it byte by byte, which would explain the high CPU usage.
If this is not the case, please add some source code to the question.

Categories

Resources