每次看到iOS的遠程消息推送,總是感覺很頭大,即便後來項目都做完了,還是覺得摸不著遠程推送的脈門,網上介紹的資料雖多,但不是寫的太簡單了,就是寫的太詳細了,不能一下抓住要點,今天終於能夠抽出點時間,來扒一扒這其中究竟有怎樣的奧秘。
根據蘋果掌控一切的習慣,消息推送也當然不能例外,不論你在哪裏推送,也不論你用什麽方式推送,都必須首先把消息發給蘋果的消息推送服務器APNs(Apple Push Notification Service),然後再由APNs發給指定的設備,也就是說消息推送的控制權完全掌握在蘋果手中。
有張很經典的圖來描述整個消息推送的過程,我們也借鑒一下
由此圖可以看出,要想進行消息推送,首先必須獲取deviceToken,由要接收消息的iOS設備向APNs發送請求,APNs根據設備的請求信息來驗證其是否合法,驗證通過之後,會給設備發來一個deviceToken,這個東東就能夠唯一標識這臺設備(貌似deviceToken是設備的identifier經過Apple私有算法而生成的,總之,知道deviceToken可以唯一標識一個設備就可以了),然後再使用deviceToken和其他資料就可以進行消息推送了。
根據我經常提到的最小系統原則(用最少的代碼實現需要的功能),遠程消息推送實際上可以分為兩步進行:
1.獲取deviceToken,只有獲取到deviceToken,才擁有向這臺設備推送消息的資格;
2.使用deviceToken作為門票向設備推送消息(當然還有其他的東東)。
所以我們可以把任務細分,第一步就是要獲取設備的deviceToken,只要能成功獲取到deviceToken,我們便成功了一半。
第一步 :獲取 deviceToken
說起來很簡單,但實際上還是需要花些功夫,這主要歸功於蘋果層層的身份驗證。
要想推送消息,必須首先申請推送證書,跟開發證書和發布證書一樣,推送證書也分為開發版和發布版兩種,當然,要獲取推送證書,也必須像開發證書和發布證書那樣向蘋果進貢,即申請付費版的蘋果開發者賬號,關於蘋果開發者賬號的相關問題可以參看我前面寫的文章,這裏不做介紹。與開發證書和發布證書不同的是,推送證書與具體的App相互綁定,也就是說,開發版和發布版證書,都可以同時服務於多個App,但是推送證書只能服務於一個App,在創建的時候就必須指定App ID,且無法修改。當然,因為這個,推送證書並不像開發證書和發布證書那樣最多都只能申請2個,推送證書並沒有個數限制。
下面正式開始我們的獲取deviceToken之旅,我假定你已經擁有蘋果開發者賬號並能夠熟練使用。
1.申請App ID
創建一個新的應用需要一個新的 App ID,申請App ID記得開啟消息推送功能
App ID申請成功後會有如下頁面
從這裏也可以看出推送證書分為開發版推送證書和發布版推送證書,黃色的 Configurable 表示還沒有創建該App ID 對應的推送證書
2.創建開發版推送證書
註意區分開發版推送證書和發布版推送證書
因為推送證書是與具體App綁定的,所以要選擇 App ID,此處選擇我們剛剛創建的 App ID
選擇證書請求文件
關於如何生成請求文件我會在後續文章中介紹
開發版推送證書申請成功,點擊 “Download” 按鈕 下載安裝
安裝成功後會自動跳轉到鑰匙串工具
這就是我們剛剛申請的開發版推送證書,與開發證書和發布證書不同的是,推送證書本身就帶有 App ID,創建的時候就與某一具體的App綁定,只能服務於一個App,前面的 “Apple Development” 表示這是一個開發版的推送證書。
此時我們再回頭去看App ID
此時 Push Notifications 的開發版選項變成綠色的 Enabled,而發布版選項依然是黃色的 Configurable,這說明我們生成了開發版的推送證書,沒有生成發布版的推送證書。
3.創建Profile文件
因為我們創建了一個新的 App ID,要想在真機上調試該應用,就必須創建相應的Profile文件,因為開發證書是通用的,所以此處可以不創建新的開發證書,但Profile文件也是與具體 App 綁定的,所以必須新建一個
Profile文件也分為開發版和發布版兩種
選擇我們剛剛創建的App ID
選擇開發證書(註意是開發證書,不是剛剛創建的推送證書),此處我使用以前創建的,如果沒有則需要創建一個新的開發證書。
選擇移動設備
給新建的Profile文件起個拉風名字,以便編譯前設置選擇
Profile文件創建成功,下載安裝
證書的問題解決了,下面就開始創建App了
4.創建 App
打開Xcode,創建一個Single View工程
工程創建成功之後,在AppDelegate.m的 didFinishLaunchingWithOptions 函數中輸入註冊遠程通知的代碼
if ([[[UIDevice currentDevice] systemversion] floatValue] >= 8.0) { //iOS8.0以後註冊方法與之前有所不同,需要要分別對待 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge) categories: nil]; [application registerUserNotificationSettings: settings]; [application registerForRemoteNotifications]; }else{ //iOS8.0以前版本的註冊方法 [application registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)]; }
成功接收到deviceToken後會回調下面的方法
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ NSLog(@"DeviceToken: %@", deviceToken); }
接收失敗調用的方法
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ NSLog(@"RegisterError: %@", error.localizedDescription); }
5. 運行 App
首先將 App 的 Bundle id 設置為我們剛剛生成的App ID
其次需要設置剛剛生成的profile文件和使用的開發版證書
然後便可以運行App了,真機上將會出現以下界面(一定要在真機上運行,模擬器無法申請到deviceToken)
該通知只會出現一次(當然把程序刪除,重新安裝又會重新出現),點擊“好”將會接收遠程消息
如果在Xcode輸出欄看到下面信息
那麽恭喜你,成功獲取到了deviceToken,尖括號內的內容就是該設備的deviceToken。
獲取deviceToken的工作完成了。
第二步:消息推送
消息推送,嚴格來說,這已經是服務器的工作了,現在市面上有很多的第三方消息推送平臺可以用來幫助我們完成此項工作,比較有名的有 極光推送、個推、小米、友盟、華為、騰訊信鴿、百度雲推送、Parse推送等等。
但是為了搞清楚推送的原理,我們還是選擇自己來實現。
不借助這些第三方平臺,我們自己也能完成簡單的推送功能,蘋果的APNs對大家來說都是一樣的,第三方無非是多了一些其他的功能。
1. 準備原材料
首先下載剛剛生成的開發版推送證書 aps_development-15.cer
其次將編譯時使用的開發證書的秘鑰導出來生成p12文件 APNsDevTest001.p12 ,千萬不要搞反了。
2.生成pem文件
由於推送服務對於Java語言,需要要用到p12格式,而 PHP語言,則要用到 pem 格式,因為我們使用的語言是PHP,所以要轉換成pem格式,使用openssl來完成轉換工作
首先將開發版推送證書文件 aps_development-15.cer 轉換成pem文件 APNsDevTestCert.pem
其次將開發證書導出的私鑰p12文件 APNsDevTest001.p12 轉換成pem文件
轉換過程需要輸入3次密碼,因為p12文件是有密碼的,所以首先驗證p12文件的密碼,正確了才能往下進行,然後輸入生成的pem文件的密碼,這個密碼要輸兩便,後面會用到。
最後將生成的兩個pem文件合並成一個pem文件,這個文件在後面服務器推送時會用到。
好了,材料已經準備好了,開始下一步工作。
3.連接蘋果推送服務器APNs,驗證證書是否可用
蘋果推送服務器也分為開發服務器和發布服務器兩個,一定要分清楚
我們現在用的是開發版消息推送服務器:gateway.sandbox.push.apple.com:2195
首先使用telnet工具測試是否可以連接蘋果APNs
如果看到以上信息,說明你的電腦可以連接蘋果APNs,按Ctrl + C 取消,否則就要去檢查是不是你的防火墻未開放2195端口
其次驗證證書是否正確,此處用到合並之前的兩個pem文件
輸入命令:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert APNsDevTestCert.pem -key APNsDevTestKey.pem
如果看到後面的信息,說明生成的證書是沒有問題的,可以進行消息推送。
4.消息推送
一切具備,開始消息推送
此處我們使用PHP語言作為推送語言
代碼不多,需要將以下幾個信息替換掉即可
a. 獲取到的deviceToken,當然需要去掉尖括號,去掉中間的空格
b. p12文件轉換成pem文件時輸入的密碼(後面輸入兩次的密碼)
c. 合並之後生成的pem文件,必須放在php文件相同的目錄下
d. 蘋果APNs地址,一定要區分清開發版APNs和發布版APNs的地址
當然,你還可以修改顯示消息的內容
下面附上PHP文件源碼
simplepush.php
<?php // Put your device token here (without spaces): $deviceToken = 'b3e6888636a6ae3e29492a293125c01d448e1bec35b0b76a3894a19ba351dcf6'; // Put your private key's passphrase here: $passphrase = '12345'; // Put your alert message here: $message = '我的推送消息!'; //////////////////////////////////////////////////////////////////////////////// $ctx = stream_context_create(); stream_context_set_option($ctx, 'ssl', 'local_cert', 'APNsDevTestCK.pem'); stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); // Open a connection to the APNS server $fp = stream_socket_client( 'ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); if (!$fp) exit("Failed to connect: $err $errstr" . PHP_EOL); echo 'Connected to APNS' . PHP_EOL; // Create the payload body $body['aps'] = array( 'alert' => $message, 'sound' => 'default', 'badge' => 99, ); // Encode the payload as JSON $payload = json_encode($body); // Build the binary notification $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; // Send it to the server $result = fwrite($fp, $msg, strlen($msg)); if (!$result) echo 'Message not delivered' . PHP_EOL; else echo 'Message successfully delivered' . PHP_EOL; // Close the connection to the server fclose($fp); ?>
確認信息無誤之後執行PHP腳本
看到上面的信息說明消息推送成功
手機端顯示(需要將應用切回後臺,應用在前臺默認是不會彈出通知消息的)
有沒有點小激動呢,偉大的工程終於完工了。
開發版的消息推送掌握了,發布版的消息推送應該也能搞定了吧,這裏就不做介紹了。
通過自己完成整個推送過程至少可以搞明白一件事,如果你無法收到遠程消息,那麽首先就要去看是否能夠獲取到deviceToken,如果獲取不到deviceToken,說明你的推送證書有問題或者是App ID 不匹配等等,如果能獲取到deviceToken,那要麽你沒有把deviceToken上傳給消息推送服務器,要麽是傳給消息推送服務器的推送證書有問題。
下面來做個總結
1.蘋果消息推送服務器APNs地址
開發版:gateway.sandbox.push.apple.com 2195
發布版:gateway.push.apple.com 2195
2.證書的時效
開發版:有效期大概四個月左右
發布版:有效期是一年
3.deviceToken的唯一性
在iOS7之前,蘋果對於一個設備上的多個App,生成相同的deviceToken,iOS7之後(包括iOS7),蘋果對於一個設備上的多個App,生成不同的deviceToken,經測試,同一個App,刪除之後重新編譯安裝,獲取到的deviceToken也不相同。也就是說一個deviceToken只能對於一個iOS設備,但一個iOS設備可以同時擁有多個deviceToken。
這種新改變導致APNs上創建了一張新老token的映射表,如果你一直用老的token,那沒問題,但是,一旦服務器使用新的deviceToken,映射表中的記錄就會被刪除,這意味著,老的deviceToken就不能用了,必然發送失敗。
4. 消息時效
如果推送的時候deviceToken對應的機器在APNs服務器上是離線狀態,蘋果會保存推送信息“一段時間”,當機器恢復在線狀態時,推送信息到該機器。如果機器長時間不在線,蘋果會拋棄掉這條消息。這個“一段時間”沒有明文說多久,而且不知道蘋果在不同情況下對這個時間有沒有動態調整,所以無法推測這個時間對於信息丟失情況的影響。
對於連續推送的情況,針對離線設備,蘋果永遠只存儲最新的一條,上一條信息會被拋棄。
有多條推送任務時,蘋果推薦使用單個連接持續發送,而不是重復的開關連接,否則會被蘋果認為D-O-S攻擊給拒絕掉。如果有多臺服務器,可以並發連接到APNS,分攤推送任務,可以更高效的執行任務。
發送多條推送任務時,如果其中有一條推送使用了錯誤的deviceToken,那麽連接就會被斷掉,導致後面的推送任務停止執行。蘋果通過一個“The Feedback Service”的服務來定期告知provider無效的deviceToken列表,如何使用這個服務參見蘋果官方文檔中的詳細說明。
5.推送原理
我們知道,iOS設備對於應用程序在後臺運行有諸多限制,考慮到手機電池電量,系統不允許應用在後臺進行過多的操作。因此,當用戶切換到其他程序後,原先的程序將無法保持運行狀態。對於那些需要保持持續連接狀態的應用程序(比如社區網絡應用),將不能收到實時的信息。為解決這一限制,蘋果推出了APNs(蘋果推送通知服務 Apple Push Notification services),APNs是解決輪詢所造成的流量消耗和電量消耗的一個比較好的解決方案。
APNs 允許iOS設備與蘋果的推送通知服務器保持常連接狀態,當你想發送一個推送通知給某個用戶的iOS設備上的應用程序時,你可以使用 APNs 發送一個推送消息給目標設備上已安裝的某個應用程序。蘋果的推送服務APNs基本原理簡單來說就是蘋果利用自己專門的推送服務器(APNs)接收來自我們自己的應用服務器發過來的需要被推送的信息,然後推送到指定的iOS設備上,再由iOS設備通知到我們的應用程序,設備以通知或者聲音的形式通知用戶有新的消息。
推送的前提是裝有我們應用的設備需要向APNs服務器註冊,註冊成功後APNs服務器會將我們的設備加入到Push服務的設備列表中,同時返給我們一個 deviceToken,拿到這個 deviceToken 後我們將這個 deviceToken 發給我們自己的應用服務器,當有需要被推送的消息時,我們自己的應用服務器會將消息按指定的格式打包,然後結合設備的 deviceToken 一並發給APNs服務器,APNs會在自己維護的Push設備列表中查找,找到匹配的設備後,將消息發送到這些設備上,實際上,此時的 deviceToken 就相當於一個設備的地址。由於我們的應用和APNs維持一個基於SSL協議的TCP流通訊長連接,APNs能夠將新消息推送到我們設備上,然後在屏幕上顯示出新消息來。
需要註意的是 App 需要每次啟動的時候都去註冊遠程通知,但是這並不會帶來額外的負擔,因為iOS系統在第一次獲得了有效的 deviceToken 之後,會本地緩存起來,以後 App 再調用 registerForRemoteNotifications: 的時候會立刻返回,並不會再進行網絡請求。這個工作由iOS系統來做,而我們的 App 層面不應該對 deviceToken 進行緩存,因為 deviceToken 也有可能變化—— 比如重裝系統或重裝應用都會造成deviceToken的改變,又或者是,用戶restore了原來的backup到新的設備上,那麽原來的 deviceToken 也會失效。
6.推送過程
Provider: 為指定iOS設備應用程序提供消息推送的服務器,即我們自己的用來推送消息給APNs的服務器
APNS: 蘋果消息推送服務器Apple Push Notification Service;
iPhone: 用來接收APNs下發下來的消息的iOS設備;
Client App:iOS設備上的應用程序,用來接收APNs下發消息的客戶端 App(消息的最終響應者)
推送過程可以歸納為以下幾步:
1.用戶iOS設備上的某個App使用設備id向APNs註冊遠程消息推送服務
2.APNs驗證請求的合法性,驗證成功後生成該設備的deviceToken,
在自己維護的Push設備列表中加入該設備,並將deviceToken返回給請求者
3.用戶App成功獲取到deviceToken之後,將deviceToken提交給自己的消息推送服務器Provider
4.有消息需要推送時,Provider會將要推送的消息和目標設備的唯一標識按指定格式打包,發給APNs
5.APNs在自己維護的Push設備列表中查找相應標識的iOS設備,找到後將消息發送給該設備
6.iOS設備接收到APNs下發的消息後,根據標識傳遞給對應的App,並按照設定格式彈出Push通知。
註意:
Provider只是把消息發送給了APNs,由APNs完成真正的推送工作,我們自己的應用服務器只是將需要推送的消息告訴蘋果服務器,至於如何維護消息隊列或如何保證消息能被推送到指定的設備上,這些工作都由APNs幫助我們完成。
deviceToken用來唯一標識一個設備,App ID用來唯一標識一個用於,二者結合就能找到指定設備上的指定應用。
7.APNs推送接口
Apple 為應用開發者提供了一個 APNs 推送接口,稱為 binary interface
最初版本的 binary interface 協議如下圖,這裏我們稱之為 v1。
Binary Interface v1

v1協議包括五個部分:第一個部分是命令標示符,第二個部分是我們的deviceToken的長度,第三部分是deviceToken 的內容,第四部分是推送消息體(payload)的長度,最後一部分也就是真正的消息內容了,裏面包含了推送消息的基本信息,比如消息內容,應用icon右上角顯示多少數字以及推送消息到達時所播放的聲音等。
v1 協議有幾個問題:
消息是否發送成功沒有明確的反饋;
如果一個消息發送失敗,比如因為 deviceToken 不合法,APNs 會在大約 500ms 後斷掉鏈接,在斷鏈前發送的消息也會發送失敗;
經我們驗證,feedback service 只會報告應用被卸載後,造成 deviceToken 失效的錯誤。而不會報告 deviceToken 不合法這種類型的推送錯誤。也就是說如果我們給一批用戶發消息,只要有一個 deviceToken 不合法,將會有可能造成若幹個用戶收不到消息。並且沒辦法確認哪些 deviceToken 不合法,哪些 deviceToken 需要被重發。這應該是 APNs 丟消息的一個重要的原因。
經過開發者不斷的向 Apple 反饋這個問題,Apple 終於推出了一個新版本的 binary interface,稱為 enhanced binary interface,我們稱這為 v2。
Binary Interface V2

我們發現,在 v1 的基礎上增加了兩個字段:
Identifier:一個任意的值,用於一條消息的識別。如果發送出現問題,錯誤應答裏會把 Identifier 帶回來。
Expiry: 離線消息超時的時間,如果為0或者小於0,APNs 不會保存這條消息。
和 v1 一樣,如果消息發送沒有問題,APNs 不會有任何返回。和 v1 不同,並且很重要的改進是,如果發送出現錯誤,v2 會在斷鏈之前返回一個錯誤應答,帶上發消息時的 Identifier 和一個錯誤碼。
error-response packet
根據這個錯誤應答,我們有機會找到是哪條消息發送出錯,並確定哪些消息需要被重發。
有一種情況,當我們將應用從設備卸載後,推送的消息改如何處理呢?我們知道,當我們將應用從設備卸載後,我們是收不到Provider給我們推送的消息的,但是,如何讓APNs和Provider都知道不去向這臺卸載了應用的設備推送消息呢?
針對這個問題,蘋果也已經幫我們解決了,那就是Feedback service。他是APNs的一部分。APNs會持續的更新Feedback service的列表,當我們的Provider將信息發給APNs推送到我們的設備時,如果這時設備無法將消息推送到指定的應用,就會向APNs服務器報告一個反饋信息,而這個信息就記錄在Feedback service中。按照這種方式,Provider應該定時的去檢測Feedback service的列表,然後刪除在自己數據庫中記錄的存在於反饋列表中的 deviceToken,從而不再向這些設備發送推送信息。
連接Feedback service的過程同樣使用Socket的方式,連接上後,直接接收由APNs傳輸給我們的反饋列表,傳輸完成後斷開連接,然後我們根據這個最新的反饋列表再更新我們自己的數據庫,刪除那些不再需要推送信息的設備的deviceToken。
從Feedback service讀取的數據結構如下:

結構中包含三個部分:
第一部分是一個時間戳,記錄設備失效後的時間信息;
第二個部分是deviceToken的長度
第三部分就是失效的deviceToken
我們所要獲取的就是第三部分,跟我們的數據庫進行對比後,刪除對應的deviceToken,下次不再向這些設備發送推送信息。
8.消息大批量發送問題
由於APNs本身機制的原因,目前easy APNs的消息發送機制為:
對每一條發送的消息,為所有需要推送的設備都在數據庫中創建一條消息,然後通過輪訓數據庫表來一條一條向蘋果消息推送服務器ANPs發送消息,也就是,如果有10W臺設備,就需要發送10W次。這種方式必然會導致在需要推送的設備較多的情況下,由於存在大量的網絡鏈接,從而產生較長時間的延遲。
也就是說,APNs消息推送不支持群發,只能一個一個發.如果你的App有100萬個用戶,就只能老老實實發100萬次。
9.消息提醒表現形式
4種:徽章、提示框、聲音和橫幅
10.消息推送機制的優點
財大氣粗的蘋果提供了一堆服務器來保障每個iOS設備和這些服務器保持了一個長連接,iOS版本更新提示,手機時鐘校準什麽的都是通過這個連接。
蘋果把這個長連接開放出來給大家推送消息用,很積德,因為這是個全球服務,幾十億臺iOS設備,服務器少說也需要上萬臺,還沒有錢可以賺。android爸爸就不做這個,於是各個App為了發消息,只能直接拼命賴在後臺維持一個長連接,電就是這樣被耗光的。
蘋果提供的APNs,只是長連接機器的一部分,你要向你的用戶發消息,必須通過APNs中轉,由Provider發給APNs,APNs轉發給你的手機,你的推送程序和用戶手機沒有直接聯系。
我們知道,iOS系統不允許應用在後臺活動,這樣做的好處我想用過iOS設備的人都知道,省電是一方面,最明顯的就是無論你安裝了多少應用,無論你打開了多少App,只要存儲空間還夠,就不用去刪除應用,不會因為程序安裝或打開太多而卡頓。
但是有了這個限制,對於終端設備,有些應用又是有必要“通知”到戶的,需要隨時與用戶主動溝通起來的,比較典型的如QQ、微信等即時通信軟件。於是,APNs應運而生。
APNs 的做法是:iOS系統自己做了個長連接,依托一個或幾個系統常駐內存的進程運作,保持與APNs之間的通訊,接管所有應用的消息推送,獨立於應用之外,而且這種長連接一直保持,即使在手機休眠的時候。對於大部分人來說,最不理解的就是,休眠時候都保持在那裏的 TCP 長連接,不會耗電很厲害麽?
答案是:不會。這是手機的設計來做到的。TCP長連接有個心跳的時間,在國外可以很長,比如30分鐘,在國內則因為網絡環境復雜一般10分鐘。客戶端發起的心跳,會短暫地消耗手機電能,但在這個心跳間隔期間,則消耗電能是很少的。當在心跳期間服務器端有推送信息過來時,客戶端可以收到並做處理。
APNs存在的好處是:
1.安全:只有身份驗證成功者才可以通過APNs推送消息
2.快速,穩定,可靠:這一點由APNs和iOS系統來保障
3.更省電:有了APNs就可以實現App無需後臺運行
4.讓整個系統的體驗更統一和簡單:不用大量 App和App的服務為了推送掛後臺,
也不會出現 App 被殺就收不到推送這種腦殘事
5.開發容易:當然,開發者還是要做些事情,比如維護個服務器什麽的,但是復雜度無疑降低了很多
當然蘋果還是要為此付出一些代價的:蘋果需要維護一個代價不小的服務器集群,而且要為服務器的宕機負責。
蘋果承擔責任,盡可能的減少了不可控的意外,保證了用戶體驗。這,只能說是公司決策者的功勞。
其實,現在手機主流平臺都有自家提供Push的功能,讓應用開發者能夠很方便地把Push能力集成到應用中。
Android: GCM (Google Cloud Messaging)
iOS: APNs(Apple Push Notification service)
Windows Phone: MPNs(Microsoft Push Notification service)。
由於Windows Phone的市場占比不高,所以一般也就沒有人會專門做WP系統的推送。
至於GCM在國內基本上是不可用的。原因主要有以下兩點:
1.國內大部分Android手機都不帶Google服務,也就用不了GCM,這是主要的問題。2.在國內Google的服務一般都不太穩定,原因你懂的。
所以現在正常在用也只有iOS平臺的APNs服務。
除了官方推送服務之外,還有很多第三方的推送服務可用,如極光推送、百度雲推送等等,但他們使用的基本技術的都是長連接和心跳包。
啰啰嗦嗦嘮叨了這麽多,最後借用一張很有意思的圖片來結束這片文章吧。
參考文章:
http://www.cocoachina.com/industry/20140528/8582.htmlhttp://www.360doc.com/content/15/0118/17/1073512_441822850.shtml
http://www.360doc.com/content/15/0414/19/1073512_463201381.shtml
http://blog.sina.com.cn/s/blog_6f9a9718010128hi.html
http://www.cocoachina.com/industry/20130321/5862.html
http://www.cnblogs.com/iphone520/archive/2013/04/16/3023687.html
http://my.oschina.net/w11h22j33/blog/208744
http://www.zhihu.com/question/20667886
Tags: 服務器 經典的 Apple 開發 蘋果
文章來源: