iOS 和 Android 的後台推送原理各是什麼?有什麼區別?


iOS 的推送
iOS 在系統級別有一個推送服務程序使用 5223 埠。使用這個埠的協議源於 Jabber 後來發展為 XMPP ,被用於 Gtalk 等 IM 軟體中。

所以, iOS 的推送,可以不嚴謹的理解為:
蘋果伺服器朝手機後台掛的一個 IM 服務程序發送的消息。
然後,系統根據該 IM 消息識別告訴哪個 Apps 具體發生了什麼事。
然後,系統分別通知這些 Apps 。

這個消息的內容是這樣的:

應該說,蘋果這種方式在技術上沒有什麼創新。但是,整個架構是很了不起的。 因為:
1
使用久經考驗的協議,技術風險小。

2
蘋果勇於承擔責任:
他需要維護一個代價不小的伺服器集群,而且要為伺服器的 down 機負責。

選擇低風險的技術方案 Bug 更少,減輕了用戶的痛苦,這是構架師的功勞。
蘋果承擔責任,儘可能的減少了不可控的意外,保證了用戶體驗。
這,只能說是公司決策者的功勞。
(從側面說明有個懂技術的 VP 是多重要。。。而 Scott 走人了。。)

他們帶給用戶的好處也是實實在在的。
1 安全。
只有登錄過的開發者可以通過蘋果的伺服器推送。

2 快速,穩定,可靠。
蘋果掌控推送伺服器和 OS 。

3 更省電。

4 讓整個系統的體驗更統一和簡單。
不會出現殺後台這種腦殘事。(不用大量 Apps / Apps 的服務為了推送掛後台)。
也不會出現 Apps 被殺就收不到推送這種腦殘事(早一點的新浪微博 Android 版仍然如此)。

5 開發容易。
當然,開發者還是要做些事情,比如維護個伺服器什麼的: http://www.ifanr.com/3979。但是複雜度無疑降低很多了。

Android 的推送
Apps 掛後台一直是 Android 引以為豪的特性(雖然我真的不知道是好處多還是壞處多。。)。。。大家掛後台等待推送就成為技術選擇。

當然, Google 事後也提供類似蘋果的推送方式了。倒也談不上抄襲,畢竟蘋果的整個技術實現也沒有什麼特別創新之處。

用戶的電池?

Apps 的開發者不會站在系統層面考慮的。他會假設其他 Apps 沒有那麼「不自覺」。而 Google 不強制的結果就是:沒人真正為用戶的電池負責。

但是, Google 的方案也並非全是悲劇:
也因為整個技術方案非強制, Android 的 Apps 在接收到推送後的表現更為靈活。
像 Line 的 Android 版本可以在推送通知的 Popup 上直接回復, iOS 就需要越獄才能做到了。

最後的話
強制和封閉,有時候並非壞事。他意味著做出這個決定的人,要為此負責。

所以,如果說蘋果的推送方案有何創新?

我以為是超越技術,不惜讓公司承擔更多風險和責任的解決方案。(類似的還有 BB 的專用網路, Kindle 的全球 3G )

個人相信,擔負起這些「額外」的責任,是值得的。。。

只要是為了用戶。


PS
勇於承擔責任的公司也更像個可靠的成年人,而不是一個隨意胡鬧的孩子。


iOS 系統的推送(APNS,即 Apple Push Notification Service)依託一個或幾個系統常駐進程運作,是全局的(接管所有應用的消息推送),所以可看作是獨立於應用之外,而且是設備和蘋果伺服器之間的通訊,而非應用的提供商伺服器。你的例子裡面,騰訊 QQ 的伺服器(Provider)會給蘋果公司對應的伺服器(APNs)發出通知,然後再中轉傳送到你的設備(Devices)之上。當你接收到通知,打開應用,才開始從騰訊伺服器接收數據,跟你之前看到通知里內容一樣,但卻是經由兩個不同的通道而來。

而 Android,就不同,更像是傳統桌面電腦系統做法。每個需要後台推送的應用有各自的單獨後台進程,才能和各自的伺服器通訊,交換數據。另外其實 Android 也有類似 APNS 的 GCM(Google Cloud Message),屬於開發者可選,非強制。(更多請看本回答評論區裡面 @Bill Cheng 的補充)

所以你大概看出來區別,iOS 的消息推送機制面世之時是一種全新的解決方案(堪稱平台中的平台),應用本身不能有常駐的後台進程,系統的開銷少,內存使用更少,電量也更少(把更多的運算和資源開銷放在雲端,非設備端)。而 Android 的特點,雖然開銷大,優點是更穩定快速,但不明顯。


更多請閱覽話題:APNs - 知乎 | http://www.zhihu.com/topic/19699063
以及開發文檔:Apple Push Notification Service (APNs) | http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html


我感覺以上的回答,並沒有正點地談到「原理「,並且我對其評判斷觀點也不認同,所以嘗試來回答下這個問題。

我的觀點是:APNs 是 iOS 成功的一個非常重要的設計!

先說原理。

iOS 的推送:就是 Apple 官方的 APNs (Apple Push Notification service)。
Android 的推送:Google 官方的是 GCM (Google Cloud Messaging)。

本質上,APNs 與 GCM 是類似的技術實現原理:即系統層有一個常駐的 TCP 長連接,一直保持的長連接,即使手機休眠的時候也在保持的長連接。

這裡對於大部分人來說,最不理解的就是,休眠時候都保持在那裡的 TCP 長連接,不會耗電很厲害么?
答案是:不會。這是手機的設計來做到的。TCP長連接有個心跳的時間,在國外可以很長比如30分鐘,在國內則因為網路環境複雜一般10分鐘。客戶端發起的心跳,會短暫地消耗手機電能,但在這個心跳間隔期間,則消耗電能是很少的。當在心跳期間伺服器端有推送信息過來時,客戶端可以收到並做處理。
這裡有篇文章以 Android 為例做原理解釋:http://blog.jpush.cn/index.php/jpush_wireless_push_principle/

再說 APNs 的設計成功處。

iOS 為了真正地為用戶體驗負責,不允許應用在後台活動。有了這個限制,但是對於終端設備,應用又是有必要「通知」到達用戶的,隨時與用戶主動溝通起來的(典型的如聊天應用)。

這就是 APNs 的邏輯所在:iOS 自己做個長駐後台保持連接。所有應用,有必要(申請)並且被允許(用戶可以改設置)的話,可以通過 APNs 中轉到達用戶。

這樣就完善了!

有可能很多人沒有真正地體會到 iOS 不允許後台應用的好處。我是 Android 開發人員,Android 手機上一般只保留幾個常用的應用,不常用就卸載。但是我的 iPhone / iPad 上則是,除非空間不足,一般不會刪除應用。
Android 就像 Windows,你要真的很費心去維護:有軟體在干背後幹壞事么?設備又給拖慢了,要清理。要考慮殺毒了。。。

Android 因為後台可以長駐,尤其是國內的 Android 的手機上 Google自家的推送服務 GCM 處於基本不可用的狀態。所以,各App各顯神通。聊天類應用的話,大多數直接借用 XMPP 規範里的一些成果。少量如微信有IM底子的,自己開發協議。這些在實現原理上與 APNs / GCM 沒有本質的區別,但有一定的技術門檻。而大多數普遍應用,要使用推送的話,則使用輪詢的方式簡單實現。

其實,國外如 Urban Airship 自己實現了 Android 上的第三方提供的推送平台。近期國內如極光推送也實現了第三方的推送平台(技術與微信、GCM、APNs類似)。理論上,如果一個 Android 設備上多款應用都使用極光推送這種第三方推送平台的話,也可以如 APNs 一樣達到節省電量、流量消耗的效果。


現在手機主流的幾個平台都有自家提供Push的功能,讓應用開發者能夠很方便地把Push能力集成到應用中。

Android 上有 GCM (Google Cloud Messaging)
iOS 上有 APNs(Apple Push Notification service)
Windows Phone 上有 MPNs(Microsoft Push Notification service)。

但是由於Windows Phone的市場佔比不高,所以一般也就沒有人會專門做wp系統的推送。至於Android的GCM在國內基本上是不可用的。原因主要有以下兩點:
一、國內大部分Android手機都不帶Google服務,也就用不了GCM,這是主要的問題。
二、在國內Google的服務一般都不太穩定,原因你懂的。
所以現在在做消息推送的時候Android平台採用伺服器與設備直接拉一條長連接的方式實現功能,而IOS平台則採用蘋果自己的APNs服務。

在分別說這兩個平台推送原理的時候,先回答一下題主關於伺服器如何先找到設備、再找到app的問題。每一個設備都有一個自己的設備號,而設備中的app又都有一個唯一的包名。所以伺服器只需要找到設備號與包名就可以定位到某個設備的某個應用,而這設備號與包名會一起構成一個標識符,叫做device_token,因此問題就簡化為把device_token與消息內容等信息交給伺服器,伺服器把內容發到唯一的device_token上。這就好像你在上海要通過順豐寄送一個快件兒給某某小區的某某房間,那麼快件兒首先會郵遞到順豐公司在北京的總站點,之後再根據小區的地址投遞/路由到某某房間,這樣一個寄件過程就算完成了。在這裡,你要寄送的快件兒就是你要發的「消息」,送達房間相當於最終「接收消息的App」,順豐公司在北京的總站點相當於這裡提到的「設備」,送達房間的房間號就相當於這個環節裡面提到的「包名」。

接下來分別簡單說一下這兩個平台的推送實現原理。
首先是IOS平台,IOS的推送是通過蘋果自己的APNs服務進行的,用戶需要將device_token以及消息內容等推送信息交給APNs伺服器,剩下的均由蘋果自己來完成。
iOS應用的推送大部分情況下都要依賴蘋果生態提供的APNs(Apple Push Notification Service)服務。
下邊用兩幅圖來簡要說明其推送原理

首先作為設備標識的device-token是由APNs頒發的,App開發者或者第三方推送平台(圖中的Provider)做的工作是收集這個device-token,APNs的推送是要求基於APNs頒發的device-token來推送的。只有正確的device-token會被APNs接受,如果是一個錯誤的、或者無效的device-token(比如App已經卸載了),APNs就不會接受。

接著開發者使用第三方推送平台(圖中的Provider)在將推送內容與範圍選定之後進行推送,第三方推送平台將信息提交給APNs,剩下的操作全部都由APNs來進行完成,整個過程第三方推送平台就不能控制了。
但是如果提供的device_token是失效的(app被卸載、系統版本升級導致device_token變化等情況)那麼推送過程就會被中斷,頻繁的斷線重連甚至會被APNs認為是一直DoS攻擊。詳情可以參考為什麼蘋果的推送,兩次推送之間間隔比較久的話,第二次推送會很慢? - 沙漠的回答
接下來是Android平台,Android平台在不使用GCM的情況下就需要將自己的伺服器或是第三方推送服務提供商的伺服器與設備建立一條長連接,通過長連接進行推送。但是不建議自己設置伺服器實現推送功能,一是因為成本太高(開發成本、維護成本),自己搭建的伺服器無論是穩定性還是速度上都比不了第三方推送服務提供商的效果。另一個是因為自己的數據量較小,使用第三方推送服務提供商可以用他們的維度進行推送,實現精準推送。友盟推送就是做的比較好的,可以根據用戶分群、地區、語言等多維度進行推送,最大程度減少對於用戶的干擾,僅把消息推送給相關用戶。友盟推送的優勢是什麼? - 李琰的回答下圖是Android平台消息推送的簡單示意圖。

開發者通過第三方推送服務提供商將信息直接下發給需要的設備,第三方推送服務提供商與設備建立一條長連接通道,並且將消息路由到APP中(圖中的設備1與設備2),對於像設備3這種無網路連接或是沒有成功建立長連接通道的設備,會在設備3連網且推送消息沒有過期的情況下自動收到由第三方推送服務提供商推送過來的消息,保證消息不會丟失。
對於消息推送想要了解更多,可以關注各推送服務提供商(友盟推送、百度雲推送、極光推送等)的官網及論壇。友盟消息推送|app推送、友盟消息推送論壇


可參考這個:
http://news.mydrivers.com/1/250/250312.htm

另外,google最近開始提供一個叫做GCM(google cloud message)的服務,如果一個應用的推送採用這種模式的話,就和@鄭紫陽 講到的iOS推送一個樣了。GCM相關的程序應該是集成在所謂的Gapps中。
除了GCM外,還有別的公司提供android的推送基礎設施的服務。


大概可能也許是這樣吧


Android的消息推送有AndroidPN,極光推送,推聊等,可以看下這個Androidpn 消息推送總結


Android用得越多,越覺得iOS的推送設計簡直是神一樣的存在。

---不是說推送技術牛逼,而且把後台/電量/卡頓這幾個複雜取捨的問題,用一種極其巧妙的方法解決了。


做過DAU有50w以上的聊天功能的網路層的Android開發。
任何push都是基於長連接,實現方式就是socket和comet。
ios的推送僅僅推送一條push消息,假如做聊天的功能,聊天消息是推不到客戶端的。iOS的push個人感覺比較雞肋。
android就方便多了,開一個service,啟動一個socket連接,定期發發心跳。


補充下:我說的這些,只是表明我之前是這麼做推送的,iOS和Android平台的優劣大家都心知肚明,這方面沒必要再起紛爭。
推送的難點在於推送協議,沒想到這塊兒沒人問及。。。唉。。。
舉個例子,微信的協議?ActiveSync?XMPP?MQTT?協議升級的兼容方案,多點登錄的同步問題,消息及時性可靠性的保證等等。

哈哈,最近又做了一個Push系統,上線之後DAU大概10w左右吧。拋棄了Comet方式,目前運營商的wap網路直接連著net網路了,核心思路和之前的都差不太多,但是推送協議是我們自己自定義的二進位協議,比之前的純文本好多了灑~


以jar的方式出現,集成於第三方客戶端,解析第三方下行的數據,並把結果透傳給第三方客戶端;也可以上行第三方定製的客戶端信息。

伺服器:

一側負責維護與成千上萬的個推SDK的長時連接,另一側與第三方伺服器對接,將第三方定製數據下行推送至個推SDK。

第三方伺服器:

數據推送的發起者,通過對接伺服器,將數據發送至第三方客戶端。

第三方客戶端:

第三方集成SDK的客戶端,推送數據正真的接收者和展現者。


iOS 系統的推送(APNS,即 Apple Push Notification Service)依託一個或幾個系統常駐進程運作,是全局的(接管所有應用的消息推送),所以可看作是獨立於應用之外,而且是設備和蘋果伺服器之間的通訊,而非應用的提供商伺服器。你的例子裡面,騰訊 QQ 的伺服器(Provider)會給蘋果公司對應的伺服器(APNs)發出通知,然後再中轉傳送到你的設備(Devices)之上。當你接收到通知,打開應用,才開始從騰訊伺服器接收數據,跟你之前看到通知里內容一樣,但卻是經由兩個不同的通道而來。

而 Android,就不同,更像是傳統桌面電腦系統做法。每個需要後台推送的應用有各自的單獨後台進程,才能和各自的伺服器通訊,交換數據。另外其實 Android 也有類似 APNS 的 GCM(Google Cloud Message),屬於開發者可選,非強制。

推送服務因為支持平台的不同和鏈路,耗流量等指標不同而受眾也不同,這裡有很多的推送服務,你也可以通過他們的特點和配置過程了解對比下,推送服務


原來差不多。就是體驗上國內外差距大。那句話說的不錯。安卓不是android.


聽樓上說的蘋果的推送機制很好用的樣子,為什麼我同學IPHONE QQ在線,我給他發消息,過了一個下午他才被推送到


目前安卓和IOS用戶體驗上最大的區別也就是消息推送機制了,如果一家獨大的安卓廠商,推廣統一的消息推送機制,強制殺掉流氓式常駐後台,那麼安卓也可以不那麼卡。


iOS 和 Android 的推送原理本質上都是一樣的,但是 iOS 對推送的這個環節的規範定義,做得非常完整,而 Android 沒有一個統一完整的規範,非常混亂。

Android 到目前為止還處在混亂狀態。


我還是喜歡通過統一推送服務去管理所有的推送消息,而不是每個APP自己都在後台開推送服務去強姦內存和電量。


其實不止APNs和GCM,像極光推送百度雲推送等其他推送的技術最基本的都是長連接和心跳包
而且話說國內沒有什麼腦殘公司會用google提供的推送服務吧(笑)
可是自己維護一個推送伺服器又是一件如此憂傷的事情
所以難道就沒有人稱讚一下牛逼的微信的推送嗎
可能是國內環境的因素,微信的推送體驗是最快的,IM廠商牛逼的優勢有沒有


整理草稿箱發現一年以前關注了這個問題,後來自己看博客各種東西也零零碎碎記了些筆記,從小白的角度上來講的,直接搬過來吧。

如果有寫的不對的地方請千萬告訴我啊!千萬記得告訴我啊!

(我發現從印象筆記那裡複製粘貼過來,一些標註、字體顏色什麼的都不見了,所以發截圖吧)

(不要在意我的破比喻,那時候剛畢業,畢業的時候被同系一個男生撩了,然後他撩完了就和我說一句他不喜歡我就想撩著好玩,大概就是這個意思。我怎麼就對帥哥這麼沒有免疫力呢!MDZZ!!!!!!!那個渣男就是阿里巴巴做安卓開發的=。=再也不想談戀愛了!!!反正這篇答案估計也沒有人看得到~)

PS:這是同一張圖但是被我截成了兩部分


國內也有不少做類似於google的開發平台,我業餘做app都是用bmob的後端雲服務平台,裡面提供很多功能,比如推送,雲存儲等等,都是免費的,你可以去看看

Bmob移動後端雲服務平台


兩個平台的解決方案各有千秋, IOS推送更注重實現藝術, Android的推送實現則充分交給了應用提供商,第三方可控的地方較多。


推薦閱讀:

GitHub 上有哪些完整的 iOS-App 源碼值得參考?
仙劍奇俠傳 5 將登錄 iPad 平台,能取得怎樣的成績?
程序員為什麼容易20~30歲比同齡人白髮多?怎麼才能避免早生白髮?
怎麼樣讓網站在 iPhone「添加到主屏幕」時顯示自定義圖標,而不是網頁截圖?
Urban Airship 是 iOS 上最好的第三方 push 服務嗎?

TAG:iOS開發 | Android開發 | ApplePushNotificationService |