ios消息推送機制及問題總結


做Android和Ios消息推送一年了,有經驗也有教訓,抽空總結一下,由於我負責的是服務端的工作,所以偏重服務端的介紹。

Ios推送的原理可以用下圖概括:

圖中,Provider是指某個iPhone軟件的Push服務器。 
APNS 是Apple Push Notification Service(Apple Push服務器)的縮寫,是蘋果的服務器。

上圖可以分為三個階段。

第一階段:應用程序把要發送的消息、目的iPhone的標識打包,發給APNS。 
第二階段:APNS在自身的已注冊Push服務的iPhone列表中,查找有相應標識的iPhone,並把消息發到iPhone。 
第三階段:iPhone把發來的消息傳遞給相應的應用程序, 並且按照設定彈出Push通知。

在實現ios消息推送之前,需要了解兩個概念:deviceToken和playload。 deviceToken類似於設備的身份證,可以定位app安裝的設備。 playload是json格式的消息載體,格式是:{"aps":{"sound":"Sent.wav","alert":"","badge":1}},當然也可以自定義參數,但是大小不能超過256個字節。
 
准備好deviceToken和playload之后,接下來需要與APNS建立SSL連接,APNS提供了兩個接口地址,分別是生產環境(gateway.push.apple.com)和測試環境(gateway.sandbox.push.apple.com),端口號都是2195。
 
當連接建立好之后,把deviceToken,playload和identifier以二進制流的形式發送給ANPS,可以維持該連接,發送多個有效的playload。由於apns是異步的,所以不會立即返回結果。
 
圖一:消息格式
 
 
當apns成功接收消息后,不會返回任何信息,只有當apns處理失敗時,才會返回錯誤信息(見圖二),第一位是數字8,第二位是狀態碼,Identifier是消息ID。
 
圖二:錯誤的信息格式:
 
開發中應避免每發送一次推送通知就建立、關閉一次連接。頻繁的建立、關閉連接可能會被  APNS  認為是  DOS 攻擊,從而拒絕發送  provider  的推送通知發送請求。
 
在JAVA中,可以使用第三方開源框架javapns給ios設備推送消息,只需簡單幾行代碼即可實現,避免了復雜的socket連接建立與消息封裝。
 
但是在使用過程中,發現javapns2.2版本兩個嚴重的bug,會造成消息的阻塞和重復發送,目前我們已經修改了javapns的源碼,修復了這兩個問題。
 
1.失敗消息重發機制:
 
javapns對於失敗消息有個重發機制,假設推送了5條消息,分別是:1,2,3,4,5,如果第3條消息失敗了,則javapns會把第3條以后的消息,也就是4,5重新推送。
看源碼:
List<PushedNotification> notificationsToResend = new ArrayList<PushedNotification>();
boolean foundFirstFail = false;
for (PushedNotification notification : pushedNotifications.values()) {
  if (foundFirstFail || !notification.isSuccessful()) {
    if (foundFirstFail) notificationsToResend.add(notification);
    else {
      foundFirstFail = true;
      skippedNotification = notification;
    }
  } }

2.消息的存儲機制:

javapns會把所有推送的消息保存在內存中,只有與apns的長連接斷開時才會清除這些消息,如果與apns的長連接始終未斷開,則這些在內存中的消息是不會被清除掉的。如果推送的消息比較多,日積月累,ios推送服務就出問題了,消息不能正常推送,必須重啟消息推送服務。

解決這兩個問題的辦法需要修改javapns的源碼。

在實際使用過程中,我們也發現,如果給apns在短時間內頻繁推送相同內容,ios設備的提醒機制就會混亂,這是apns的問題,我們無法解決,只能盡量避免出現這種情況。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM