淺談iPhone 中Push 功能原理 推送通知
iPhone 中Push 功能原理 推送通知是本文要介紹的內容,主要講述了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進行解鎖的 過程,是不經過iT
unes的,而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 中Push 功能原理 推送通知的內容介紹完了,希望本文對你有所幫助。