简体   繁体   中英

Sending message to gcm topic

I'm trying to send a message to some topic, but for some reason the message take a lot of time to be delivered and some times I receive too many messages at once, I also noticed that some of the new messages arrive before other older messages.

pubSub.subscribe(token, "/topics/" + topic, null);

The code to send messages:

JSONObject jsonGcmData = new JSONObject();
JSONObject jsonData = new JSONObject();
jsonData.put("message", message);

if (topic != null)
{
    jsonGcmData.put("to", "/topics/" + topic);
}
else
{
    // TODO: handle this
    jsonGcmData.put("to", "/topics/Fail");
}

jsonGcmData.put("data", jsonData);

URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key=" + API_KEY);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);

OutputStream outputStream = conn.getOutputStream();
outputStream.write(jsonGcmData.toString().getBytes());

InputStream inputStream = conn.getInputStream();

There is a couple of things that contribute to issues you are facing.

Before all, if you are developing a new app, you should use Firebase Cloud Messaging , which supersedes Google Cloud Messaging . It will not yet be shut down, but why put yourself in a bad situation one day. Nevertheless, the version is probably not the cause.

First, you must know that GCM/FCM messages are not instant. It depends what do you consider real-time, but in general they might have some latancy and they can be batched into groups to conserve energy, bandwith, CPU time and so on. That is default behavior when the priority is set to normal , as in your case. Set the priority to high , if you want a greater chance for the message to be instantly delivered. Be warned that this might affect battery life. I cannot say in which degree, but the warning is there by a reason.

You might also set the time_to_live to 0 , but than you have almost no guarantee and no retries.

Second, an issue I am afraid you cannot solve easily, ordering. FCM does not guarantee any kind of ordering, period.

So, what can you do? First, you can create some kind of buffer in your application which will wait for some time for messages to receive, reorder them and pass them through the logic. That means you should include some kind of timestamp with every message on send or some kind of global counter on each message so you know if you missed some (beware, this solutions carries dragons with it!). Second, organize your messaging, and logic as a matter of fact, so it is more resilient on out of order messages.

Finally, depending on your application, maybe you can switch protocols. Consider something like MQTT, STOMP or even websockets.

All in all, not a trivial problem, but feasable to solve for normal operation. If you are building something really mission critical around this, good luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM