APNS 是蘋果為IOS設(shè)備提供的推送服務(wù),全稱是(Apple Push Notification service)。 如果你有接觸移動互聯(lián)網(wǎng)相關(guān)的開發(fā)的話,應(yīng)該對它很熟悉。
接下來我會給大家簡單介紹一下Python下的一些APNS相關(guān)的模塊以及其特點(diǎn)。
模塊介紹:
PyAPNs
項(xiàng)目地址: https://github.com/djacobs/PyAPNs
PyAPNs是我最早使用的APNS模塊,它應(yīng)該是我要介紹的所有模塊里面最簡單的,最新的源碼 只有384行,實(shí)現(xiàn)了APNS的基本功能,包括發(fā)送推送、使用Frame群發(fā)推送、feedback 接口等。
它的所有驗(yàn)證都是在客戶端做的,比如每一個Payload不超過256字節(jié)。
簡單來說,就是盡量復(fù)用你的鏈接,不要頻繁的建立和斷開,不然會被當(dāng)做DoS攻擊處理。所以 我們使用它來發(fā)送推送時應(yīng)該這么干:
... ...# 復(fù)用這個gateway_serverapns.gateway_server.send_notification(token_hex, payload)
復(fù)用這個gateway_server也就是連接,但是到APNS Server的鏈接是很不穩(wěn)定的,很多情況下 都會被斷開,比如網(wǎng)絡(luò)原因、發(fā)送了非法的token等。所以我們還需要一個重連的機(jī)制。
但PyAPNs模塊沒有為你處理這些,所以你需要自己去處理那些出錯的情況,這也是使用 這個模塊最不方便的地方。
所以我的建議是,除非你自己需要去寫一個APNS的Provider,那你可以以這個模塊作為起點(diǎn)。 否則,如果你想在你的項(xiàng)目里面快速用上推送服務(wù)的話,建議還是選擇別的模塊。
示例:
import timefrom apns import APNs, Frame, Payload apns = APNs(use_sandbox=True, cert_file='cert.pem', key_file='key.pem') # Send a notificationtoken_hex = 'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b87'payload = Payload(alert="Hello World!", sound="default", badge=1)apns.gateway_server.send_notification(token_hex, payload) # Send multiple notifications in a single transmissionframe = Frame()identifier = 1expiry = time.time()+3600priority = 10frame.add_item('b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b87', payload, identifier, expiry, priority)apns.gateway_server.send_notification_multiple(frame) # Get feedback messagesfor (token_hex, fail_time) in apns.feedback_server.items():# do stuff with token_hex and fail_time對于更復(fù)雜的alerts,比如自定義按鈕,可以使用PayloadAlert類alert = PayloadAlert("Hello world!", action_loc_key="Click me")payload = Payload(alert=alert, sound="default")pyapns(twisted)
項(xiàng)目地址: https://github.com/samuraisam/pyapns
他們使用的就是這個項(xiàng)目作為他們的推送服務(wù)的provider,所以我之后把推送從PyAPNs遷移到了這個項(xiàng)目, 使用下來其實(shí)還是挺不錯的,這個項(xiàng)目的主要特點(diǎn)是:
它其實(shí)是一個基于twisted的server,所有發(fā)送推送的請求都通過它來和蘋果的服務(wù)器交互。
對Django和Pylons有原生支持。
支持多個APP。
因?yàn)楹吞O果的推送服務(wù)器是由這個provider維持的長連接,所以你每次發(fā)送推送的時候都直接 這個provier進(jìn)行叫交互,這樣的的好處是每一次的接口調(diào)用返回都很快,真正推送到蘋果服務(wù)器的過程 則是由這個provider異步來完成。
但是這個模塊很長時間都沒有維護(hù)了,其實(shí)Apple那邊的協(xié)議在這段時間里已經(jīng)進(jìn)行了一些更新。 但這個模塊沒有跟上。
我使用這個模塊碰到的最大的問題就是 群發(fā)推送的效果得不到保證。
雖然這個模塊的demo里面有對批量發(fā)送推送進(jìn)行支持,但是我的使用經(jīng)驗(yàn)是,這個模塊的群發(fā) 推送效果比較差,而且缺少從蘋果Server拿到錯誤反饋的邏輯。
因?yàn)門wisted的代碼風(fēng)格實(shí)在不怎么喜歡,所以我群發(fā)碰到問題后開始尋找別的解決方案。
apns-client
項(xiàng)目地址: https://bitbucket.org/sardarnl/apns-client/
總結(jié)一下就是:
維持持久鏈接。SSL協(xié)議的握手環(huán)節(jié)是很慢的。當(dāng)每一個連接被建立之后,它應(yīng)該一直保持最少幾分鐘來等待 下一次的推送。
支持改進(jìn)過的的協(xié)議格式。Apple的程序員們設(shè)計(jì)了一個臭名昭著的推送協(xié)議。他們更新了一個版本,這個版本可以讓你知道 每一次群發(fā)推送里面到底是哪一個單獨(dú)的消息出了問題。
清晰的Python API
沒有把驗(yàn)證這塊寫進(jìn)代碼里,而是直接返回APNS的錯誤信息
使用這個模塊來發(fā)送推送也很簡單:
from apnsclient import *# 可以使用Session對象來維持連接池session = Session()con = session.get_connection("push_sandbox", cert_file="sandbox.pem")# 發(fā)送推送和得到反饋messge = Message(["my", "device", "tokens"], alert="My message", badge=10)# Send the message.srv = APNs(con)res = srv.send(message)# Check failures. Check codes in APNs reference docs.for token, reason in res.failed.items(): code, errmsg = reason print "Device faled: {0}, reason: {1}".format(token, errmsg)# Check failures not related to devices.for code, errmsg in res.errors: print "Error: ", errmsg對于我來說,這個模塊最大的優(yōu)點(diǎn)就是為你處理了連接有可能被異常斷開重連的情況。而且代碼不像 pyapns這樣晦澀,更直觀,可讀性更高。所以你如果要在它的基礎(chǔ)上做一些修改也沒有任何問題。
經(jīng)過我的使用經(jīng)驗(yàn),使用apns-client來處理百萬級別這種量級的推送沒有任何問題,到達(dá)率也很好。
所以如果你沒有特殊的需求的話,apns-client應(yīng)該是你最好的選擇。
新聞熱點(diǎn)
疑難解答
圖片精選