iPhone 的 Push(推送通知)功能原理淺析

 


第一部分:Push原理
(以下絕大多數內容參考自、圖片來自iPhone OS Reference Library)
機制簡介
Push 的工作機制可以簡單的概括爲下圖
圖中,
Provider是指某個iPhone軟件的Push服務器。 
APNS 是Apple Push Notification Service(Apple Push服務器)的縮寫,下文統一使用該縮寫。 
因 此,整個過程可以分爲三個階段,下面用大家常用的聊天客戶端BeejiveIM來說明。(BeejiveIM是一款支持多賬戶登錄的支持Push的 iPhone聊天客戶端,支持MSN、Google Talk等)
此時Provider爲BeejiveIM服務器,我們在 BeejiveIM上登陸MSN,其實軟件是先把登錄信息發送到BeejiveIM服務器,再通過其服務器來登陸MSN。因此,當我關 閉了BeejiveIM,BeejiveIM服務器會繼續爲我登陸MSN,此時如果有人對我的MSN賬戶發送了消息,那麼就會觸發Push。此時:
第 一階段:BeejiveIM服務器把要發送的消息、目的iPhone的標識打包,發給APNS。 
第二階段:APNS在自身的已註冊Push服務 的iPhone列表中,查找有相應標識的iPhone,並把消息發到iPhone。 
第三階段:iPhone把發來的消息傳遞給相應的應用程序, 並且按照設定彈出Push通知。 
Push認證
許多朋友說Push不能用。其中一大部分,就是在認證階段就出了問題。想了解原因?請細 看:
這裏所說的認證機制,實際上包含兩層。一層是物理連接上的認證,另一層則纔是涉及到iPhone 設備令牌的認證。
物理連接上的認證:SSL/TLS鏈接
(如果你瞭解TLS,那麼這裏我幾乎無需介紹。)
iPhone在開啓Push的時候,會連接 APNS建立一條TLS加密鏈接。每一臺正常的iPhone都有一個獨有的設備證書,而APNS也有一個服務器證書。兩者建立的時候,會驗證彼此的證書有 效性。
TLS鏈接一旦建立,在沒有數據的情況下,只需要每隔15分鐘進行一次保活的握手,因此幾乎不佔流量。而 一旦因爲意外原因導致鏈接中斷,iPhone會不斷重新嘗試建立TLS鏈接,直到成功。
更高一層次:基於token(令牌)的認證
在機制 簡介裏,我提到過APNS判斷Push推送消息該發給哪臺iPhone的依據是一個“目的iPhone的標識”,這個 標識就是device token(設備令牌)
設備令牌是怎麼生成的呢?是每次建立TLS 連接時,APNS通過前一層次(TLS層)裏我們提到的每臺正常的iPhone唯一的設備證書(unique device certificate),並用令牌密鑰(token key)加密生成的。
在令牌生成了之後,APNS會把設備令牌(device token)返回給iPhone,而對應的Push應用程序(如BeejiveIM),則把返回來的設備令牌(device token)直接發送給Provider(如BeejiveIM服務器)。這樣,當Provider有Push消息要發送時,就會把對應 帳號的設備令牌(device token)和消息一起發送給APNS,而APNS再依據設備令牌(device token),找到相應TLS鏈接的iPhone,併發送相應的Push消息
以上覆雜的流程可以歸納爲下面這幅圖:
圖中,Client App是iPhone上的Push應用程序。(圖中缺了一條(當有Push消息時)由Provider到APNS的鏈接)
最重要的部分——每臺 iPhone獨有的設備證書和密鑰的來歷
正常的iPhone刷系統之後,是沒有設備證書和密鑰的。這就是爲什麼iPhone會需要連接到 iTunes上進行激活——激活過程中,Apple會分配給每臺iPhone獨一無二的設備證書(device certificate)和密鑰(key)
以上我僅僅介紹了從iPhone到APNS的鏈接建立。其實從Provider到 APNS也有一條TLS鏈接,但是與本文關係不大,所以不多加介紹了。
我的PUSH問題出在哪裏?
相信許多同學都抱有這樣的疑問。
正 如上文提到的,iPhone的Push需要APNS生成對應iPhone的設備令牌,但生成這個令牌又需要iPhone上的有效的設備證書(device certificate)和密鑰(key),但是:
iPhone OS 3.X 使用blacksn0w進行解鎖的 過程,是不經過iTunes的,而blacksn0w本身又不生成對應的設備證書(device certificate)和密鑰(key),因此這樣解鎖完的iPhone根本不可能與APNS建立任何的TLS鏈接,Push自然廢 了。
有關各種pushfix補丁
要修補這個問題,唯一的辦法就是重新生成唯一且有效的設備證書(device certificate)和密鑰(key)
但是要知道,證書是需要機構簽發的,自己一個人隨便弄的一個證書,只會被APNS 認爲是無效證書。(SSL證書一個多少錢大家可以去查查)
並且對應的文件似乎還和iPhone本機的一些內容相關,不是直接製作好的文件放進去就 可以的。
於是,最早,dev team推出了一個測試版補丁,Push fix by dev team(通過他們的twitter發佈的,因此官網沒有消息)。這個補丁初期很有效。但是僅在iPhone 2G上比較正常。
之後某人士發佈 pushfix 1.0了。由於使用了不同的生成方法,因此在新版本iPhone上也正常工作了。於是風靡一時。
然而,以上兩個 補丁都有嚴重的隱患——他們使用了一個固定的證書作爲設備證書(device certificate)。因此在不同iPhone上的區別僅僅在於生成的密鑰(key)不同。(待確認)
上面提到 過,APNS依靠每臺iPhone獨一無二的設備證書(device certificate)和密鑰(key)來生成獨一無二的設備令牌(device token),用來標識每臺iPhone。
但當多個iPhone的設備證書(device certificate)完全一致時,就存在一定機率使得多個iPhone獲得相同的設備令牌(device token)
而 隨着這兩個補丁的使用人數不斷增加,使得出現獲得相同設備令牌(device token)的iPhone數量大大增加了。
當 這些相同設備令牌(device token)的iPhone上啓用了同一個應用程序的Push的時候,就極有可能出現彼此間的Push串發的現象。——如某論壇目前N多人抱怨QQ的 Push到別人iPhone上的情況就是如此。
之後,Pushfix的作者,聲稱自己可以爲每臺iPhone手 工製作唯一的設備證書(device certificate)和密鑰(key),並且開始提供了付費服務,並且最終推出了付費的 Pushfix 2.0——其通過cydia安裝的原理是,在安裝的時候在線連接到pushfix站點檢查對應iPhone的imei確定是否付費再自動下載對應的證書。
雖 然不知道他是怎麼製作這些證書的。但是經過曉曉的驗證,他製作的證書確實是有效的。Push問題確實修復了。
在這之後,某論壇上出現了一個叫做 Pushfix_D的補丁,聲稱無需付費也能直接修復問題。然而,
——考慮到一些情況,我決定把對Pushfix_D的判斷用英文發出來。當然, 製作者肯定很清楚下面寫的東西:)
it contains the same released push keys from back in July 2009.  Everybody gets the same key, so it is going to have all the same problems of ALL the free push fixes.  Push isn't going to work very long and it is going to drain your battery.
其他出錯的情況
我的iPhone在 cmwap下無法push?!
對的,這完全正常。在wap網內,TLS鏈接幾乎無法建立成功。
我的iPhone在Wi-Fi下無法 push?!
實際上這得說是iPhone與某些無線路由器的不兼容。如果無線路由器開啓了DNS轉發功能,那 麼很有可能你的iPhone無法成功與APNS服務器建立TLS鏈接。
解決方法:
關閉無線路由器的DNS轉發功能,手動爲iPhone的 Wi-Fi連接設置DNS爲8.8.8.8
補充,實際上,這也就是爲什麼iPhone連接到Wi-Fi上而又不能收到Push的時候,會變得發熱 且非常耗電。因爲iPhone會不斷嘗試建立TLS鏈接
如何得知我的Push是否破解成功?
一個簡 單的方法就是安裝 Twitbird Pro版本。在其Accounts頁面,會顯示當前軟件的Push註冊狀況。
或者你可以用WinSCP之類 的軟件查看iPhone上的
/var/mobile/Library/Preferences/com.apple.apsd.plist
文 件狀態。
如果其大小爲119字節,則說明該iPhone已經成功取得了設備令牌(device token),並保存在該文件中。 
如果 小於該大小,則說明該iPhone已經和APNS鏈接過,但是未能取得設備令牌(device token)。 
如果沒有該文件,那說明該 iPhone根本沒能成功連接到APNS。 
其他一些值得注意的問題
iPod Touch與iPhone的Push機制不完全相同,鎖屏後15分鐘方檢查一次。故請勿與上文對號入座。 
APNS在發送Push消息時,如果發 現對應的iPhone鏈接中斷,則會延後幾分鐘再發送。超過一個時間後,Push消息會被刪除。因此請注意你的網絡狀況是否影響Push正常工作。 
如上文所說,每臺iPhone的設備令牌(device token)儲存在/var/mobile/Library/Preferences/com.apple.apsd.plist 文件中。這就是爲什麼每次需要重裝Push補丁時,建議刪除push程序並刪除該文件。 
使用sbsettings的EDGE開關關閉EDGE, 卻不關閉Push的話,會導致iPhone不斷嘗試建立TLS連接,最終耗盡電量。因此,如果你不打算或不能用Push,請關閉Push選項。 
對軟件的Push服務器(Provider)而言,Wi-Fi與手機網絡是一樣的,在Push處理上不會有任何區別。 
雖然已經解釋的很清楚,但還 是明說一句,只要TLS連接正常,Push服務就是實時的,速度僅取決於Provider而已。 
題外話,iPhone上的郵件推送爲Push Mail技術,與本文所說的Push完全不同。請查閱Exchange Direct Push相關內容。 
福利
一句話,如果你覺得 Push沒什麼用,那隻能說明你見識太少。在以下頁面可以查看一些支持Push的優秀軟件。
http://appadvice.com/applists/show/definitive-list-of-push-capable-apps
內容參考:iPhone OS Reference Library
轉自:http://xiaolife.com/wordpress/an-introduce-to-iphone-push/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章