Python使用HTTP2實現蘋果原生推送
說起蘋果的推送,可能很多開發人員就開始頭疼了,因為實現蘋果推送服務是1個比較蛋疼的事情,于是便引入了第3方推送平臺,比如極光、信鴿之類的服務。
由于蘋果原生APNs蛋疼的協議,致使本來很簡單的1個推送服務讓人望而卻步。直到蘋果最近的HTTP2協議的出現才有所改善。
一直以來,http2這樣新潮的名字都只能出現在nodejs、go這樣的編程語言中。在網上輸入關鍵字http2,點擊進去就會發現各種各樣使用nodejs實現的HTTP2服務器,利用nginx版本1.9.5版本搭建HTTP2服務之類的文章。這些文章確實讓人熱血沸騰、激動人心。
然而,在Python中遲遲不見有任何的實現,不免覺得已經落伍了。實際上,在項目過程中更多追求的是穩定和健壯,更多關于新潮的技術只能先看看。比如最近比較火的直播節目,實際上用Python也是可以完全實現的,而且性能還是挺不錯的。
下面是一些編程語言使用HTTP2的原生推送的實現:
- node-apn ,1個基于nodejs語言的實現。
- apns-http2 ,1個基于Java語言的實現
- apns2 ,1個基于Go語言的實現
而在Python中,還完全停留在舊的Binary API的版本中,而唯一的1個HTTP2的實現 PyAPNs2 在Python2中不能正常的運行。不過,不要灰心,下面我們自己動手寫1個。
在這里,我們簡單的通過Python來實現以下內容:
- 原生APNs推送
- 推送的異常處理
下面我們分別來進行說明。
文檔說明
首先來看下官方的文檔,如果你直接從百度上進行搜索然后進行點擊后會發現對應的鏈接跳轉是1個404頁面,關于這個問題已經在 蘋果APNs推送頁面丟失問題 中進行說明了,其跳轉后的地址如下:
而實際對應頁面的地址應該如下所示:
由于蘋果官方采用了HTTP2協議,相比之前的Binary API而言,可以說簡化了很多內容,自然而言代碼也精簡了很多。
依賴的庫
為了實現HTTP2的推送服務,我們需要安裝hyper這個庫,它是1個Python實現的HTTP2的客戶端,我們可以通過pip進行安裝。
而該庫主要依賴于cryptography、pyOpenSSL這2個庫,因此我們需要提前安裝好cython和openssl的C庫開發文件。
pipinstallhyper
實際代碼
安裝完成hyper后,我們可以通過如下的方式來實現1個推送服務:
fromhyperimportHTTPConnection, tls
token = 'xxxxxx-xxxxx-xxxx-xxxxx'
payload = {
'aps': {
'alert': '測試推送',
'sound': 'default',
'badge': 1,
}
}
headers = {
"apns-topic": '證書的主題名稱',
}
conn = HTTPConnection('api.development.push.apple.com:443', ssl_context=tls.init_context(cert='證書文件名稱'))
conn.request('POST', '/3/device/%s' % token, body=json.dumps(payload), headers=headers)
resp = conn.get_response()
d = resp.read()
可以看到,這個推送服務的核心代碼只有寥寥3行就已經完成了。在這里,我們通過HTTPConnection連接到蘋果推送服務器的443端口上,然后我們初始化推送證書。
之后我們通過POST方法請求蘋果的推送服務器,在這里需要傳遞要推送的設備的Token,然后推送的內容為1個JSON的格式,最后再附對應的頭信息即可。
如果推送失敗后,蘋果的推送服務器會返回1個錯誤的信息。下面是1個HTTP2推送成功后的截圖:
而后是Binary API推送的接口的截圖:
可以看到,我們成功的接收到了推送的消息。相比舊的Binary API接口,HTTP2的推送服務的速度快2倍以上,在測試的時候,基本上在5s內就可以收到,而舊的接口基本上等待15-30s才可以收到。
而在HTTP2協議中,主要有以下一些響應的狀態碼:
- 200,推送成功。
- 400,請求有問題。
- 403,證書或Token有問題。
- 405,請求方式不正確,只支持POST請求
- 410,設備的Token與證書不一致
開源的實現
上述推送服務雖然簡單,但是操作起來還是挺繁瑣了,特別是錯誤處理這塊。在這里,要感謝我隔壁哥們的辛勤付出,他對上述的代碼進行了封裝并進行了開源。
我們可以通過pip直接進行安裝:
pipinstallapplepush
然后我們只需要在代碼中進行如下的調用即可:
fromapplepushimportApplePush
apns = ApplePush('證書文件名稱', 'bundle ID')
resp = apns.single_push('蘋果設備token', "推送內容")
而返回的結果類似如下:
{
'status': 成功為200,錯誤為其它,
'headers': {
'apns-id': 蘋果推送返回的UUID,
},
'data': 蘋果接口返回的字符串,
'error_msg': 錯誤原因,如果推送成功為None
}
然后我們根據返回的結果與實際業務進行結合。
結語
雖然通過Python使用HTTP2來實現蘋果的推送服務是1個比較簡單的事情,甚至會覺得比較枯燥無味的事情。
但是,如果你從Binary API到HTTP2,把這2個協議研究一遍,再把證書的簽名及轉換的內容過一遍 ,或許你會收獲更多。
當然,在這個過程中還有其他一些內容,比如根據證書內容來自動實現識別推送環境(測試還是生產),進而不同的推送版本,以及如何嵌入C庫來實現更快的HTTP2推送服務都是可以實現的。
參考文章:
https://imququ.com/post/nginx…
http://hyper.readthedocs.io/e…
來自:http://python.jobbole.com/86847/