發(fā)表日期:2018-04 文章編輯:小燈 瀏覽次數(shù):2568
接下來我們分別對新舊協(xié)議進行一下介紹:
反人類的舊APNs協(xié)議設(shè)計
在介紹新版 APNs 前,讓我們來吐槽下舊的基于二進制的 APNs 協(xié)議設(shè)計是多么反人類:
在理論上,推送分發(fā)的服務(wù)器要打開一個同 APNs 網(wǎng)關(guān)服務(wù)器的
連接,并保持這個連接。但在舊的協(xié)議下,APNs 服務(wù)卻不保證 socket 能維持這個連接。如果通道上沒有消息往來,空閑下來到話,socket將被路由掐斷。也就是說:APNs 連接說斷就斷,而你無能為力。有意思的是:在舊的協(xié)議下,如果服務(wù)器響應(yīng)成功的話,你將不會收到任何回應(yīng),但是如果服務(wù)器響應(yīng)失敗(例如,使用了一個非法的 Push token),服務(wù)器將返回了一個錯誤編碼,并關(guān)閉這個socket。最重要的是,你必須重新發(fā)送使用這個無效 token 以后發(fā)送的所有推送(詳情見示意圖)。因此,你可能一直不能確定你的推送是否成功的被 APNs 服務(wù)器接收。
成功了不響應(yīng),失敗了才響應(yīng),這個是最大的反人類。于是許多開發(fā)者想到了一個很 tricky 的辦法:利用這個“漏洞”,比如在每發(fā)送10條后故意發(fā)送一個錯誤的token,如果APNs有響應(yīng)了,就可以確認 APNs 是處在可用狀態(tài)的,進而確認這10條消息是發(fā)送成功的。如果沒有響應(yīng)就說明可能連接已經(jīng)中斷,那么這10條消息很可能是丟失的,然后做進一步的處理。但代價顯而易見:將導致你們的推送系統(tǒng)性能低下。(本文中所說到“你們的推送系統(tǒng)”,如果是使用的第三方的SDK完成的推送服務(wù),那么就是指SDK提供商所搭建的推送系統(tǒng)。如果是你們公司自己搭建的推送系統(tǒng),那么就是指你們自己的推送系統(tǒng)。)蘋果有一個名為"feedback"的服務(wù),我們可以定時調(diào)用這個服務(wù)來獲取invalid tokens的列表。這個服務(wù)你只要調(diào)用一次就可以獲得所有的invalid tokens 列表。所以,如果一個應(yīng)用使用了很多不同公司的推送SDK,他們將會爭奪資源去輪詢查找invalid tokens列表。invalid token越多,你們的推送系統(tǒng)性能將越低。而且 APNs 只要一發(fā)生錯誤就關(guān)閉這個連接,然后重新連接。也就是“重啟” socket 連接。
示意圖:
enter image description here
圖中的 PN2 去哪里了?它被放到了 feedback 列表里,等待下次你調(diào)用 feedback 服務(wù),然后重發(fā)。
為什么Apple要在舊APNs中設(shè)計出“重啟”的策略?
為了效率。
就像PC機出問題,我們總說“重啟能解決90%的問題”。
為了理解“重啟”策略,我們可以類比下,熟悉 Erlang/OTP 的朋友可能知道, Erlang/OTP 在處理錯誤方面有獨到之處:監(jiān)督樹(supervision trees)。大致來說,每一個 Erlang 進程都由一個監(jiān)督進程發(fā)起并監(jiān)視。當一個進程遇到了問題的時候,它就會退出。當進程退出的時候,其監(jiān)督進程會將其重啟。
(這些監(jiān)督進程由一個引導進程(bootstrap process)發(fā)起,當監(jiān)督進程遇到錯誤的時候,引導進程會將其重啟)
其思想是,快速的失敗然后重啟比去處理錯誤要快。像這樣的錯誤處理看起來跟直覺相反 —— 當錯誤發(fā)生的時候通過放棄處理來獲得可靠性。但是重啟的確是解決暫時性錯誤的靈丹妙藥。
這也可能讓你想到 DNS 服務(wù)發(fā)展史:
DNS 在設(shè)計之初是基于 UDP 的,顯然這樣的設(shè)計不能滿足當今社會的準確性的需求,于是涌現(xiàn)了如 DNSPod 這樣的基于 HTTP 的 DNS 解析服務(wù)。但是當時為什么這樣設(shè)計,實際也很好理解,UDP 效率高,一來一回網(wǎng)絡(luò)上傳輸?shù)闹挥袃蓚€包,而 HTTP則需要三次握手三個包,再一拆包,就需要四個包。這是受限于當時整個社會的帶寬水平較低,而現(xiàn)在沒人會感激 UDP 所節(jié)省的流量,所有人都在詬病DNS污染問題。這樣你也許就理解了,為什么舊的 APNs 設(shè)計如此反人類。這個是必經(jīng)階段。
那么接下來就讓我們看看Apple為解決這些問題而推出的基于 HTTP/2 的全新 APNs 協(xié)議。
基于 HTTP/2 的全新 APNs 協(xié)議
來看下新版的 APNs 的新特性:
Request 和 Response 支持JSON網(wǎng)絡(luò)協(xié)議
APNs支持狀態(tài)碼和返回 error 信息
APNs推送成功時 Response 將返回狀態(tài)碼200,遠程通知是否發(fā)送成功再也不用靠猜了!
APNs推送失敗時,Response 將返回 JSON 格式的 Error 信息。
最大推送長度提升到4096字節(jié)(4Kb)
可以通過 “HTTP/2 PING ” 心跳包功能檢測當前 APNs 連接是否可用,并能維持當前長連接。
支持為不同的推送類型定義 “topic” 主題
不同推送類型,只需要一種推送證書 Universal Push Notification Client SSL 證書。
示意圖:
enter image description here
其中最大的變化就是基于了 HTTP/2 協(xié)議,采用了長連接設(shè)計,并提供 “HTTP/2 PING ” 心跳包功能檢測、維持當前 APNs 連接,解決了老 APNs 無法維持連接的問題。
而且新增的狀態(tài)碼特性,也解決了這個問題:無法獲知消息是否成功地從你們的推送系統(tǒng)投遞到了 APNs 上。理論上,你們可以保證消息是100%投遞到了APNs的,因為你可以準確的知道哪條消息到達了APNs,哪些沒到。重發(fā)特定失敗消息成為可能。
所以上文開頭的吐槽中第一條,有一句是“不到位的”,因為現(xiàn)在SDK的提供商能夠準確地告訴你哪些消息推送到APNs了,哪些沒有。
順便介紹下 HTTP/2:
HTTP/2 是 HTTP 協(xié)議發(fā)布后的首個更新,于2015年2月17日被批準。它采用了一系列優(yōu)化技術(shù)來整體提升 HTTP 協(xié)議的傳輸性能,如異步連接復用、頭壓縮等等,可謂是當前互聯(lián)網(wǎng)應(yīng)用開發(fā)中,網(wǎng)絡(luò)層次架構(gòu)優(yōu)化的首選方案之一。
Apple 對于 HTTP/2 的態(tài)度也非常積極,2015年5月 HTTP/2 正式發(fā)表后不久,便在緊接著6月召開的WWDC 2015大會中,向全球開發(fā)者宣布,iOS 9 開始支持HTTP/2。
而且如果我們要使用 HTTP/2,那么在網(wǎng)絡(luò)庫的選擇上必然要使用 NSURLSession。
我們都知道 HTTP/2 是復用 TCP 管道連接的,而且 HTTP/2 也以高復用著稱,這也使新的 APNs 協(xié)議更加高性能。(題外話:這點也同樣體現(xiàn)在 NSURLSession 底層對于每個 session 是對多個 task 進行連接的復用。)
Universal Push Notification Client SSL 證書
在開發(fā)中,往往一條內(nèi)容,需要向多個終端進行推送,終端有:iOS、tvOS、 and OS X devices, 和借助iOS來實現(xiàn)推送的 Apple Watch。在以往的開發(fā)中,不同的推送,需要配置不同的推送證書:我們需要配置:dev證書、prod證書、VOIP證書、等等。而從2015年12月17日起,只使用一種證書就可以了,不再需要那么多證書,這種證書就叫做Universal Push Notification Client SSL 證書(下文統(tǒng)一簡稱:Universal推送證書)。
改進了,但仍需改進。還是有坑
APNs的確改進來不少,但仍有需要改進對地方。還是有坑:
除了獲取TLS證書比較復雜未解決外,還有一些坑:
文章開頭提到過以下這種情況:
很遺憾的告訴你,你的吐槽是“到位的”:你以后還得忍受這種反人類的設(shè)計。
這中間發(fā)生了什么?
當 APNs 向你發(fā)送了多條推送,但是你的設(shè)備網(wǎng)絡(luò)狀況不好,在 APNs 那里下線了,這時 APNs 到你的手機的鏈路上有多條任務(wù)堆積,APNs 的處理方式是,只保留最后一條消息推送給你,然后告知你推送數(shù)。那么其他三條消息呢?會被APNs丟棄。
有一些 App 的 IM 功能沒有維持長連接,是完全通過推送來實現(xiàn)到,通常情況下,這些 App 也已經(jīng)考慮到了這種丟推送的情況,這些 App 的做法都是,每次收到推送之后,然后向自己的服務(wù)器查詢當前用戶的未讀消息。但是APNs也同樣無法保證這多條推送能至少有一條到達你的 App。很遺憾的告訴這些App,這次的更新對你們所遭受對這些坑,沒有改善。
為什么這么設(shè)計?APNs的存儲-轉(zhuǎn)發(fā)能力太弱,大量的消息存儲和轉(zhuǎn)發(fā)將消耗Apple服務(wù)器的資源,可能是出于存儲成本考慮,也可能是因為 Apple 轉(zhuǎn)發(fā)能力太弱。總之結(jié)果就是 APNs 從來不保證消息的達到率。并且設(shè)備上線之后也不會向服務(wù)器上傳信息。
所以上文開頭的吐槽中第一條,也有一句是“到位的”,因為現(xiàn)在SDK的提供商依然無法保證,消息推到了 APNs,APNs能推到 App 那里。
但Google Cloud Messaging就有這些特性。而且 GCM 現(xiàn)在也支持iOS設(shè)備了,那么 APNs 和 GCM 現(xiàn)在就形成了競爭關(guān)系。讓我共同期待 APNs 在2016年6月的 WWDC 的能有新的改進吧。
對App開發(fā)的影響
想使用新協(xié)議,如果你用的第三方推送,這里最明顯的操作,就是你必須更新到支持新協(xié)議的SDK版本。因為新協(xié)議需要 SDK 上傳你 app 的 bundle id ,生成各個平臺推送用的 topic。如果你們自己搭建的服務(wù),則需要你自己上傳。老協(xié)議不用上傳。
新 APNs 支持 iOS6 等全版本推送內(nèi)容達4096字節(jié),舊 APNs 是14年6月之前只支持256字節(jié),在此之后支持 iOS8 以上2048字節(jié)。以前受限于推送字節(jié),比如推文章 url,開發(fā)者選擇超出256后推送id,甚至不判斷直接推 id,接收后再請求完整 url。一旦請求錯誤,推送內(nèi)容可能丟失。現(xiàn)在可以避免了。
如何創(chuàng)建 Universal Push Notification Client SSL 證書
現(xiàn)在你知道什么是 Universal Push Notification Client SSL 證書了,那么如何創(chuàng)建它?
what is Universal Push Notification Client SSL Certificate
圖中其他方式,就叫做非 Universal 方式(下文簡稱:非 Universal 推送證書):
what is not Universal Push Notification Client SSL Certificate
這里也推薦使用 Universal 推送證書來進行推送服務(wù)。詳細的創(chuàng)建步驟如下所示:
前往蘋果開發(fā)者中心進行登錄,并點擊 “Certificates, Identifiers & Profiles”。
enter Certificates, Identifiers & Profiles
選擇在 Certificates 欄下的“All”。
點擊下圖中紅色邊框內(nèi)的加號按鈕。
Create SSL certificate
選擇 “Production” 欄下的 “Apple Push Notification service SSL (Sandbox & Production)” 勾選后,點擊下一步。
Select push certificate
從 App ID 下拉菜單中選擇你需要的 App ID ,點擊下一步。
select App ID
這時會出現(xiàn) About Creating a Certificate Signing Request (CSR)。
guide to create a CSR
根據(jù)它的說明創(chuàng)建 Certificate Signing Request。
how to create a CSR
點擊下圖中的 “Choose File” 按鈕:
upload CSR File
上傳剛剛生成的 .certSigningRequest 文件 生成 APNs Push Certificate。
下載證書。
雙擊打開證書,證書打開時會啟動鑰匙串訪問工具。
在鑰匙串訪問工具中,你的證書會顯示在 “證書” 中,注意選擇左下角的 “證書” 和左上角 “登錄”。
confirm create cer success
結(jié)束語
對于 APNs 而言,iOS9 的這一更新是有劃時代意義的,請即刻敦促你們公司的服務(wù)端進行升級,或者使用支持新 APNs 協(xié)議的 SDK 進行推送服務(wù)。 文中如有錯誤,并請幫忙指正,反饋請發(fā)往微博@iOS程序犭袁。
轉(zhuǎn)載自iOS程序犭袁
日期:2018-04 瀏覽次數(shù):7014
日期:2017-02 瀏覽次數(shù):3706
日期:2017-09 瀏覽次數(shù):3991
日期:2017-12 瀏覽次數(shù):3792
日期:2018-12 瀏覽次數(shù):5140
日期:2016-12 瀏覽次數(shù):4827
日期:2017-07 瀏覽次數(shù):13890
日期:2017-12 瀏覽次數(shù):3758
日期:2018-06 瀏覽次數(shù):4503
日期:2018-05 瀏覽次數(shù):4687
日期:2017-12 瀏覽次數(shù):3787
日期:2017-06 瀏覽次數(shù):4201
日期:2018-01 瀏覽次數(shù):4195
日期:2016-12 瀏覽次數(shù):4155
日期:2018-08 瀏覽次數(shù):4639
日期:2017-12 瀏覽次數(shù):4007
日期:2016-09 瀏覽次數(shù):6756
日期:2018-07 瀏覽次數(shù):3425
日期:2016-12 瀏覽次數(shù):3467
日期:2018-10 瀏覽次數(shù):3605
日期:2018-10 瀏覽次數(shù):3724
日期:2018-09 瀏覽次數(shù):3832
日期:2018-02 瀏覽次數(shù):3847
日期:2015-05 瀏覽次數(shù):3754
日期:2018-09 瀏覽次數(shù):3526
日期:2018-06 瀏覽次數(shù):3652
日期:2017-02 瀏覽次數(shù):4095
日期:2018-02 瀏覽次數(shù):4598
日期:2018-02 瀏覽次數(shù):4471
日期:2016-12 瀏覽次數(shù):3791
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.