2014/10/30

GCM推播訊息(notification)延遲問題

最近在開發Android APP,使用到GCM(Google Cloud Message),發現一個問題:
我們的server已經送出notification,可是Android phone/table有時很快(兩三秒)就收到推播訊息,有時則等超過10分鐘才收到。

雖然Google宣稱notification不保證即時送達,也不保證可以送達,不過我們還是希望在免費的服務下,能夠儘可能的即時送達
對有些應用而言,超過5分鐘就真的很久了

工程師個性使然,總是想找出是我們的server+APP有問題,還是其他因素造成。因為有時是即時就能收到,照理說應該不是server或APP的問題
找了andQlimax的po文,覺得他的測試與推論是合理的,也符合我所觀察到的狀況

手機/平板與GCM server間是透過TCP connection來進行通訊。當手機/平板連上網路時,Android就與GCM server建立連線。為了維持連線,手機/平板會定期送出heartbeat訊號到GCM server。andQlimax觀察到如果是使用3G/4G連線,則每28分鐘會送一次heartbeat;若是用WiFi則是15分鐘。(為什麼間距那麼大?這除了要考慮手機平板的耗電外,還有GCM server的負擔等等)

andQlimax認為一般電信服務商(3G/4G)或WiFi router(無線分享器...),就資源分配與使用效率等考量,通常不會無限維持這麼多的TCP connection(因為可以建立的connection數是有限的),因此這些設備(3G/4G:基地台; WiFi:無線分享器/HotSpot)會定期(例如每5分鐘)檢視那些connection是idle的(沒有傳送資料),就將這個connection關掉。

因為Android的heartbeat間距很長,所以手機平板與GCM server間的TCP connection會被關掉,因此當有訊息時,GCM server便無法透過原來建立的connection將訊息送到手機平板,必須等到手機端時間到要發heartbeat時,才會重新建立連線。
所以當connection還沒有被關掉,或是heartbeat週期很快又到了,手機平板就能很快的接收到推播訊息;若是connection被關了,那就得等到下一次送heartbeat時才能收到notification了。

andQlimax在很多論壇與管道都呼籲Google/Android應該修改heartbeat的傳送週期。不過看來到目前Google都尚未採納。

如果,真的有mission critical的應用,也許應考慮是不是用long-polling request等機制來作,而不依賴GCM。