GCM消息传递时间非常不稳定

时间:2012-10-22 17:00:46

标签: android message google-cloud-messaging

我已经设置了一个支持GCM的Android应用程序,并且有一个小测试应用程序可以向应用程序发送一个消息。 当我在模拟器中运行App时,我可以看到(通过记录msgs)它向GCM注册并获得令牌。

然后,当我将令牌放入我的测试应用程序并让它发送一个消息时,结果显示发送了1个消息,0个失败,0个更改了ID。

有时,msg几乎立即出现,有时需要20分钟。 星期五,我的2个测试消息花了15分钟和20分钟。 我今天早上发送的前2个是立即的,下一个尚未出现 - 它只有10分钟......

我能做些什么来让交货时间一直很快?随机延迟20分钟将是一个不可接受的条件。

6 个答案:

答案 0 :(得分:30)

我们遇到了同样的问题,但它在网络与网络之间存在差异。我们认为这是家庭中枢路由器(Virgin Super Hub)在五分钟不活动后断开连接。您可以通过每两分钟发送一个空的GCM消息进行确认,以保持连接活动。

以下是对我们所做工作的更深入的解释:https://groups.google.com/d/msg/android-gcm/Y33c9ib54jY/YxnCkaPRHRQJ

答案 1 :(得分:4)

您不能保证快速交付,因为GCM到设备的连接可能很差,因为CommonsWare指出。但是,在传送列车中存在两种可能的延迟:1)GCM连接到电话(如前所述)和2)实际从GCM服务器发送的消息的延迟。如果在发送应用程序中将'time_to_live'参数设置为0秒,则至少可以测试延迟发生的位置。

值为0秒表示将立即发送消息,如果传递失败,则将在GCM服务器上丢弃该消息。它对于现实生活的使用并不具有实用价值,但可以让您找出交付列车的哪个部分导致延误。

答案 2 :(得分:2)

据报道,GCM存在一个相当严重的问题,即保持心跳不能如此可靠。因此,由于它仅每15分钟(通过3G)或28分钟(通过Wifi)发送一次,如果由于某种原因服务器连接被丢弃,它可能无法在几分钟内恢复。

这些类型的恶作剧促使开发出一种解决方案,该解决方案不依赖第三方网络为离线(后台)Android应用程序提供大规模可扩展且可靠的推送通知。

https://help.pubnub.com/entries/21720011-Can-my-Android-App-Receive-Messages-While-Inactive

答案 3 :(得分:2)

这确实是由Google云消息传递中的不切实际的心跳间隔引起的。

这可能是GCM中最令人沮丧的错误。 GCM通过维护从Android设备到Google服务器的空闲套接字连接来工作。这很好,因为它几乎不消耗电池电量(与轮询相反),并且它允许设备在消息到达时立即被唤醒。为了确保连接保持活动状态,Android将在移动连接上每28分钟发送一次心跳,在WiFi上每15分钟发送一次心跳。如果心跳失败,则连接已终止,GCM将重新建立连接并尝试检索任何挂起的推送通知。心跳间隔越高,消耗的电池越少,设备从睡眠中唤醒的次数就越少。

但是,这需要付出很大的代价:心跳间隔越长,识别断开的套接字连接所需的时间就越长。在部署GCM之前,Google尚未在现实​​生活中充分测试这些时间间隔。这些间隔的问题是由网络路由器和移动运营商引起的,他们在几分钟不活动后断开空闲套接字连接。通常,这在廉价的家用路由器中更常见,其制造商决定空闲套接字连接的最大寿命,并终止它以节省资源。这些路由器只能处理有限数量的并发连接,因此采取这种措施来防止过载。这导致终止GCM套接字,并且当需要传递GCM消息时,它不会到达设备。设备只会在0到28分钟后发送心跳时才会意识到连接已断开,导致推送通知在某些情况下无效(例如,当消息对时间要求严格时)。根据我的经验,大多数便宜的路由器在大约5-10分钟不活动后终止空闲连接。

我写了一篇关于此问题和其他GCM问题的文章:

http://eladnava.com/google-cloud-messaging-extremely-unreliable/

Google Cloud Messaging的替代方案

Pushy(https://pushy.me/)是一个独立的推送通知网关,完全独立于GCM。它保持自己的后台套接字连接,就像GCM一样,用于接收推送通知。底层协议是MQTT,一种极轻量级的发布/订阅协议,利用非常少的网络带宽和电池。

Pushy的一个巨大优势是,用于发送推送通知(来自服务器)以及注册设备以进行推送通知的代码实际上可以在GCM和Pushy之间互换。这使得在实施GCM之后切换到Pushy非常容易,并且由于其不稳定而不得不放弃它。

(完全披露:我为自己的项目创立了Pushy,并意识到许多应用程序将从这样的服务中受益)

答案 4 :(得分:0)

这件事对我很重要。

我在一秒计时器处理程序中设置了此代码,每2分钟发送一条GCM消息。希望是它能保持活力

            if ((mOneSecondTick %120) == 0){
            // q 1 minute check when we got last call....
            long lDiff = System.currentTimeMillis() - GCMlastCall;
            if (PushAndroidActivity.GCMAvailable){
                Log.d("pushAndroidActivity",String.format("(mOneSecondTick %d",lDiff));
                if (lDiff > 122 * 1000){ // more than a minute
                    Intent intent = new Intent(StayInTouch.this,PushAndroidActivity.class);
                    2startActivity(intent);
                }else{ // every 2 minutes send out a gcm message...
                    asyncWebCall(String.format(AgeingLib.GCMTICKLE,androidid),0);
                    return; // only if it sends a tickle and all is well...
                }
            }else{
                Log.d("pushAndroidActivity",String.format("(mOneSecondTick mod60 no GCM on this device"));
            }
        }

GCMlastCall是收到消息的最后一次,因此我们可以判断gcm是否已停止。

已经工作了几天现在好了

答案 5 :(得分:-1)

  

我能做些什么来确保交货时间一直很快?

在生产中,交付时间将变化很大,因为移动设备是移动的,因此具有可变的连接性,超出GCM内部的任何交付问题。