Google Cloud Messaging service is higly unreliable under some circumstances:
when the target device temporarily loses connectivity, some messages are lost
and others are sent two times from the GCM server to the device. I tested this
behaviour using this simple server, written in python, that establish an XMPP
connection to Google's server and send a GCM message to a (previously
registered) device every 5 seconds:
#!/usr/bin/python
import sys, json, string, xmpp, time
SERVER = 'gcm.googleapis.com'
PORT = 5235
USERNAME = "Your GCM Sender Id"
PASSWORD = "Your API Key"
REGISTRATION_ID = "Registration Id of the target device"
unacked_messages_quota = 100
send_queue = []
def send(json_dict):
template = ("<message><gcm xmlns='google:mobile:data'>{1}</gcm></message>")
client.send(xmpp.protocol.Message(
node=template.format(client.Bind.bound[0], json.dumps(json_dict))))
def flush_queued_messages():
global unacked_messages_quota
while len(send_queue) and unacked_messages_quota > 0:
send(send_queue.pop(0))
unacked_messages_quota -= 1
client = xmpp.Client('gcm.googleapis.com', debug=['socket'])
client.connect(server=(SERVER,PORT), secure=1, use_srv=False)
auth = client.auth(USERNAME, PASSWORD)
if not auth:
print 'Authentication failed!'
sys.exit(1)
last = int(round(time.time()))
count = 0
while True:
client.Process(1)
flush_queued_messages()
now = int(round(time.time()))
elapsed = now - last
if (elapsed > 5):
count += 1
last = int(round(time.time()))
print 'Sending GCM message with message_id: ' + 'id-' + str(count)
send_queue.append({'to': REGISTRATION_ID,
'message_id': 'id-' + str(count),
'data': {'message_destination': 'test',
'message_id': 'id-' + str(count)},
'delivery_receipt_requested': True})
On the target device (a Nexus 5 with Android 5.0.1) I installed a client app
that register for GCM and receive the messages with a BroadcastReceiver:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("GCM Demo", "Received GCM message with message_id: " + intent.getExtras().getString("message_id"));
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
}
Now I execute the python server and at some point simulate a connectivity loss
on the device (enabling airplane mode) for some seconds. The logacat on the
target device shows:
--- Start the python server ---
01-16 12:03:04.373 I/GCM Demo( 8667): Received GCM with id: id-1
01-16 12:03:10.380 I/GCM Demo( 8667): Received GCM with id: id-2
01-16 12:03:16.544 I/GCM Demo( 8667): Received GCM with id: id-3
--- Device disconnected (airplane mode enabled) ---
[...]
--- Device reconnected (airplane mode disabled) ---
01-16 12:04:09.993 I/GCM Demo(11376): Received GCM with id: id-1 <-- duplicate
01-16 12:04:09.996 I/GCM Demo(11376): Received GCM with id: id-2 <-- duplicate
01-16 12:04:10.002 I/GCM Demo(11376): Received GCM with id: id-3 <-- duplicate
01-16 12:04:10.008 I/GCM Demo(11376): Received GCM with id: id-4
01-16 12:04:10.013 I/GCM Demo(11376): Received GCM with id: id-5
01-16 12:04:10.018 I/GCM Demo(11376): Received GCM with id: id-6
01-16 12:04:10.138 I/GCM Demo(11376): Received GCM with id: id-7
01-16 12:04:10.173 I/GCM Demo(11376): Received GCM with id: id-8
01-16 12:04:10.189 I/GCM Demo(11376): Received GCM with id: id-9
<-- id-10 missing!
<-- id-11 missing!
01-16 12:04:10.210 I/GCM Demo(11376): Received GCM with id: id-12
01-16 12:04:36.161 I/GCM Demo(11376): Received GCM with id: id-12 <-- duplicate
01-16 12:04:36.183 I/GCM Demo(11376): Received GCM with id: id-13
<-- id-14 missing!
<-- id-15 missing!
<-- id-16 missing!
<-- id-17 missing!
<-- id-18 missing!
01-16 12:04:52.415 I/GCM Demo(11376): Received GCM with id: id-19
01-16 12:04:58.401 I/GCM Demo(11376): Received GCM with id: id-20
--- Stop the python server ---
As you can see, after the device reconnect to the internet, Google resend
duplicate messages for ids 1,2 and 3 (and after some time for the id 12 too),
and the messages with ids 10,11,14,15,16,17,18 are never delivered to the
device. Note that when the python server send the messages to Google's server,
it immediately receive an ACK for all the 20 messages, so all the messages are
correctly sent to Google GCM infrastucture.
Original issue reported on code.google.com by kungu...@gmail.com on 16 Jan 2015 at 11:28
Original issue reported on code.google.com by
kungu...@gmail.com
on 16 Jan 2015 at 11:28