轉自:http://xiaolife.com/wordpress/an-introduce-to-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上的Direct Mail為Push Mail技術,與本文所說的Push完全不同。請查閱Exchange Direct Push相關內容。
福利
一句話,如果你覺得 Push沒什麼用,那隻能說明你見識太少。在以下頁面可以查看一些支援Push的優秀軟體。
http://appadvice.com/applists/show/definitive-list-of-push-capable-apps
內容參考:iPhone OS Reference Library