Google Cloud Messaging – сообщения, полученные мгновенно или с большой задержкой

Я использую Google облачные сообщения в моем последнем проекте года для колледжа. Все работает нормально, но у меня были проблемы с GCM. Довольно регулярно сообщения либо доставляются практически мгновенно, либо с большой задержкой.

Я прочитал это, и я действительно не думаю, что это применимо в этом случае:

GCM обычно доставляет сообщения сразу после их отправки. Однако это не всегда возможно. Например, устройство может быть отключено, отключено или иным образом недоступно. В других случаях сам отправитель может запросить, чтобы сообщения не доставлялись до тех пор, пока устройство не станет активным, используя флаг delay_while_idle. Наконец, GCM может преднамеренно задерживать сообщения, чтобы приложение не потребляло чрезмерные ресурсы и отрицательно влияло на срок службы батареи.

В моем проекте говорилось не более 5 или 6 сообщений с сервера в минуту. Если GCM можно использовать для приложения чата, то они не смогут блокировать сообщения, которые отправляются / получаются с такой скоростью? Это стало довольно раздражать и будет довольно плохо, если мой проект работает только 50% времени …

Вот мой код для сообщения, которое отправляет сервер:

@Override public void run() { Message.Builder messageBuilder = new Message.Builder().delayWhileIdle(false); Gson gson = new Gson(); messageBuilder.addData("profile", gson.toJson(profile)); databaseConnection.notifyDevices(messageBuilder.build()); } public void notifyDevices(Message message) { Sender sender = new Sender(xxx); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("message", message.toString())); //LOG System.out.println("Notifying devices with the following message \n \"" +message+ "\""); List<String> deviceIDsList = new ArrayList<String>(); String [] deviceIDArray; //Get devices to notify List<JSONDeviceProfile> deviceList = getDevicesToNotify(); for(JSONDeviceProfile device : deviceList) { deviceIDsList.add(device.getDeviceId()); try { sender.send(message, device.getDeviceId(), 5); } catch (IOException e) { System.out.println("Error sending GCM message!"); e.printStackTrace(); } } } 

И мой метод Android onMessage:

 @Override protected void onMessage(Context arg0, Intent intent) { String message = intent.getStringExtra("profile"); Log.d(TAG + "Received Message: ", "Received Message: " + message.toString()); //CALL NEW INTENT WITH PROFILE DETAILS Intent displayProfileIntent = new Intent(arg0, DisplayProfile.class); displayProfileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); displayProfileIntent.putExtra("message", message); startActivity(displayProfileIntent); /* //generateNotification(arg0, username); handler.post(new Runnable() { @Override public void run() { //Toast.makeText(getApplicationContext(), username, Toast.LENGTH_SHORT).show(); } }); */ } 

Я надеюсь, что у кого-то была аналогичная проблема, я просто хочу подтвердить, что проблема – это то, что я делаю, или если она не в моих руках.

Tl; dr GCM-сообщения поступают мгновенно или примерно через 10 минут (задержка обычно согласована).

Часть фреймворка GCM на клиентском телефоне использует TCP-соединение на порту 5228. Это соединение используется для push-уведомлений, но, как и каждое соединение tcp, он может пойти на тайм-аут с некоторыми маршрутизаторами / операторами, которые применяют строгие политики для уничтожения неактивных подключений tcp ( Tcp idle timeout ).

Большинство маршрутизаторов wifi убивают неактивные соединения через 5 минут, например, мои.

Рамка GCM использует механизм keep-alive для отправки сетевого пакета в сети каждые 15 минут на Wi-Fi и каждые 28 минут на 3G. Этот keep-alive не всегда надежный для всех пользователей.

Я открыл проблему для google здесь: https://productforums.google.com/forum/#!category-topic/nexus/connecting-to-networks-and-devices/fslYqYrULto. Они соглашаются, что в настоящее время проблема.

EDIT (2014/01/08) : в настоящее время Google обновляет интервалы между часами до 8 минут для беспроводных и мобильных соединений. Tha'ts удаленное изменение, которое воздействует на все устройства Android 2.2. Это хорошее улучшение, чтобы избежать тайм-аута соединения tcp push. Тем не менее, если Wi-Fi-маршрутизатор убивает неактивные соединения через 5 минут, у вас будет 3 (8-5) минут задержки в push-уведомлениях (если у вас не было других уведомлений, поддерживающих соединение)

EDIT (2016/03/06) : теперь Google, похоже, тестирует мою обратную связь 2 года назад, чтобы иметь динамический механизм для определения правильного интервала сердцебиения в зависимости от сети. В настоящее время, похоже, поэтапное развертывание и только для Wi-Fi, поскольку я знаю. Таким образом, на основе SSID Wi-Fi алгоритм определяет интервал правого интервала для конкретного Wi-Fi с каким-то ступенчатым уточнением. Этот звук очень хорош! Это удаленное изменение, которое влияет на каждый Android-телефон с сервисами Google Play.