標籤:ios apple apns push 推送
簡介
Apple Push通知機制其實很簡單,就是Apple的APNs伺服器做為中間人,把訊息推送到對應的裝置上。
一張來自Apple文檔的圖:
當然,看起來簡單,但是還有一些實際的問題。
比如,如何區分Provicer的?如何區分裝置的?
簡單而言,是這樣的:
- 每個應用都有一個自己的認證(certificate),開發人員可以從蘋果那裡獲得;
- 應用可以到APNs伺服器上註冊(register),然後得到一個device_token,開發人員要自己儲存好,推送時就要用這個來區分不同的裝置。
- 注意,token並不是裝置唯一標識碼。token是可以改變的,因此APNs提供了一個feedback服務,開發人員可以得到失效的token。
- 對於每個裝置只儲存最後的一條push,所以如果連續發很多條push,裝置沒有及時接收的話,後面的push會覆蓋前面的。
- Provider和APNs伺服器,APNs伺服器和使用者裝置之間的通迅都是SSL/TLS協議的。這點要比國內的推送服務商要做的好,國內的推送服務都是http介面的,完全沒有加密。
- Push都是對於裝置而言的。所以敏感資訊不要通過push來傳遞。
- Push是盡量送達的,Push訊息可能會丟失,所以不要用Push來傳遞可靠資料。
Apple Push的協議蛋疼之處
上面只是有一些要注意的小地方,下面來說下真正蛋疼的東西:Apple Push的協議。
首先,明顯的是設計不良:
協議裡的command,現在實際上也用來表示Version。
比如command = 0, 1, 2就分別表示發送訊息的三個版本。
更蛋疼的是前面0,1兩個版本現在的文檔都找不到了。這個讓維護老代碼的人情何以堪?想調試下bug,結果發現官方文檔都消失了,那得多蛋疼。
Apple的文檔裡只說到:
Field name |
Length |
Discussion |
Command |
1 byte |
Populate with the number 2 . |
可能在你看這篇文章的時候,變成了“Populate with the number 3”了。。
正常人看到這裡只會覺得一頭霧水,為什麼這個command是2?怎麼想得到這個Command居然是和版本相關的。。我是從別的一些實現代碼裡才知道有三個版本的。
協議格式混亂
比如這個feedback的格式:
deviceToken就是固定好了是32位元組的,前面還要加一個Token length。
有人可能說,這是考慮了以後token大於32位元組的。那乾脆應該為feedback的回應包加上版本號碼。
寄件者可以批量發送訊息,但是只有出錯的時候才會返回出錯訊息的ID。
這個乍看起來,沒什麼問題。但是當你想要實現一個Push用戶端的時候,就知道蛋疼之處了:
寄件者連續發了1,2,3,4 ... 100 條訊息,已經寫到socket裡去了,這裡APNs伺服器回應說第57條訊息失敗了。
那寄件者得從第58條開始,重新再發。那寄件者得把前面已經發送出去了的訊息緩衝起來!
好的,緩衝一下也沒關係,那麼到底緩衝多少個訊息呢?1024個?2048個?天知道。
要是寄件者的網速快,一下子把4096個訊息都發出去了呢?那怎麼辦?
好吧,也許你會說4096個訊息體比較大小,Apple的伺服器的TCP socket緩衝區都滿了,你發不了這麼多的訊息。
我只是想發個Push訊息而已,難道還要推算APNs伺服器的socket緩衝區的大小?要是它的網路架構也做了緩衝呢?要是寄件者的網路架構也做了緩衝呢?
是不是每次發送時,都要等待資料全都寫到socket裡去了?
開發人員測試用的沙箱伺服器是個擺設
文檔上寫了在開發環境可以用這個網域名稱,gateway.sandbox.push.apple.com。但是坑爹的是,這個網域名稱實際上是個擺設,你可以建立SSL串連,也可以正常發送訊息。
但是你的裝置卻是收不到訊息的。要是在實現自己的用戶端時,用這個來測試,就蛋疼了,一次次檢查自己的代碼,看是否有問題,最終卻發現是對方的伺服器有問題。。
只有程式員才能明白這種蛋疼的心情。
不支援分組發送
現在的國內流行的推送服務,如百度推送等,都支援分組的配置,這樣大大節省了頻寬,提離了發送效率。
可能還有一些蛋疼的地方,忘記了,下篇blog說下一些實現自己的用戶端要注意的事項及一個Java的實現ZPush。
參考:
http://support.apple.com/kb/HT3576?viewlocale=zh_CN&locale=zh_CN
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW12
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW1