Python搭建APNS苹果推送通知推送服务的相关模块使用指南


Posted in Python onJune 02, 2016

APNS 是苹果为IOS设备提供的推送服务,全称是(Apple Push Notification service)。 如果你有接触移动互联网相关的开发的话,应该对它很熟悉。

接下来我会给大家简单介绍一下Python下的一些APNS相关的模块以及其特点。

模块介绍:

PyAPNs

项目地址: https://github.com/djacobs/PyAPNs
PyAPNs是我最早使用的APNS模块,它应该是我要介绍的所有模块里面最简单的,最新的源码 只有384行,实现了APNS的基本功能,包括发送推送、使用Frame群发推送、feedback 接口等。

它的所有验证都是在客户端做的,比如每一个Payload不超过256字节。
简单来说,就是尽量复用你的链接,不要频繁的建立和断开,不然会被当做DoS攻击处理。所以 我们使用它来发送推送时应该这么干:

... ...

# 复用这个gateway_server
apns.gateway_server.send_notification(token_hex, payload)

复用这个gateway_server也就是连接,但是到APNS Server的链接是很不稳定的,很多情况下 都会被断开,比如网络原因、发送了非法的token等。所以我们还需要一个重连的机制。

但PyAPNs模块没有为你处理这些,所以你需要自己去处理那些出错的情况,这也是使用 这个模块最不方便的地方。

所以我的建议是,除非你自己需要去写一个APNS的Provider,那你可以以这个模块作为起点。 否则,如果你想在你的项目里面快速用上推送服务的话,建议还是选择别的模块。

示例:

import time
from apns import APNs, Frame, Payload
 
apns = APNs(use_sandbox=True, cert_file='cert.pem', key_file='key.pem')
 
# Send a notification
token_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 transmission
frame = Frame()
identifier = 1
expiry = time.time()+3600
priority = 10
frame.add_item('b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b87', payload, identifier, expiry, priority)
apns.gateway_server.send_notification_multiple(frame)
 
# Get feedback messages
for (token_hex, fail_time) in apns.feedback_server.items():
# do stuff with token_hex and fail_time
对于更复杂的alerts,比如自定义按钮,可以使用PayloadAlert类
alert = PayloadAlert("Hello world!", action_loc_key="Click me")
payload = Payload(alert=alert, sound="default")

pyapns(twisted)

项目地址: https://github.com/samuraisam/pyapns
他们使用的就是这个项目作为他们的推送服务的provider,所以我之后把推送从PyAPNs迁移到了这个项目, 使用下来其实还是挺不错的,这个项目的主要特点是:

它其实是一个基于twisted的server,所有发送推送的请求都通过它来和苹果的服务器交互。
对Django和Pylons有原生支持。
支持多个APP。
因为和苹果的推送服务器是由这个provider维持的长连接,所以你每次发送推送的时候都直接 这个provier进行叫交互,这样的的好处是每一次的接口调用返回都很快,真正推送到苹果服务器的过程 则是由这个provider异步来完成。

但是这个模块很长时间都没有维护了,其实Apple那边的协议在这段时间里已经进行了一些更新。 但这个模块没有跟上。

我使用这个模块碰到的最大的问题就是 群发推送的效果得不到保证。

虽然这个模块的demo里面有对批量发送推送进行支持,但是我的使用经验是,这个模块的群发 推送效果比较差,而且缺少从苹果Server拿到错误反馈的逻辑。

因为Twisted的代码风格实在不怎么喜欢,所以我群发碰到问题后开始寻找别的解决方案。

apns-client

项目地址: https://bitbucket.org/sardarnl/apns-client/
总结一下就是:

维持持久链接。SSL协议的握手环节是很慢的。当每一个连接被建立之后,它应该一直保持最少几分钟来等待 下一次的推送。
支持改进过的的协议格式。Apple的程序员们设计了一个臭名昭著的推送协议。他们更新了一个版本,这个版本可以让你知道 每一次群发推送里面到底是哪一个单独的消息出了问题。
清晰的Python API
没有把验证这块写进代码里,而是直接返回APNS的错误信息
使用这个模块来发送推送也很简单:

from apnsclient import *

# 可以使用Session对象来维持连接池
session = Session()
con = session.get_connection("push_sandbox", cert_file="sandbox.pem")

# 发送推送和得到反馈
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

对于我来说,这个模块最大的优点就是为你处理了连接有可能被异常断开重连的情况。而且代码不像 pyapns这样晦涩,更直观,可读性更高。所以你如果要在它的基础上做一些修改也没有任何问题。

经过我的使用经验,使用apns-client来处理百万级别这种量级的推送没有任何问题,到达率也很好。

所以如果你没有特殊的需求的话,apns-client应该是你最好的选择。

Python 相关文章推荐
Python3利用SMTP协议发送E-mail电子邮件的方法
Sep 30 Python
Python中django学习心得
Dec 06 Python
Python程序运行原理图文解析
Feb 10 Python
python中数据爬虫requests库使用方法详解
Feb 11 Python
Python3.6笔记之将程序运行结果输出到文件的方法
Apr 22 Python
Python两个字典键同值相加的几种方法
Mar 05 Python
python读取指定字节长度的文本方法
Aug 27 Python
opencv3/C++图像像素操作详解
Dec 10 Python
keras load model时出现Missing Layer错误的解决方式
Jun 11 Python
selenium自动化测试入门实战
Dec 21 Python
浅谈Python数学建模之固定费用问题
Jun 23 Python
Python如何利用pandas读取csv数据并绘图
Jul 07 Python
Python的Django框架中使用SQLAlchemy操作数据库的教程
Jun 02 #Python
实例解析Python中的__new__特殊方法
Jun 02 #Python
详解Python中的__new__、__init__、__call__三个特殊方法
Jun 02 #Python
Python实现优先级队列结构的方法详解
Jun 02 #Python
KMP算法精解及其Python版的代码示例
Jun 01 #Python
Python缩进和冒号详解
Jun 01 #Python
Python注释详解
Jun 01 #Python
You might like
Discuz! Passport 通行证整合
2008/03/27 PHP
PHP中$_FILES的使用方法及注意事项说明
2014/02/14 PHP
Yii把CGridView文本框换成下拉框的方法
2014/12/03 PHP
php实现网站顶踩功能的完整前端代码
2015/07/19 PHP
php实现将数组或对象写入到文件的方法小结【三种方法】
2020/04/22 PHP
ext 代码生成器
2009/08/07 Javascript
ajax 缓存 问题 requestheader
2010/08/01 Javascript
js获取指定的cookie的具体实现
2014/02/20 Javascript
jQuery的3种请求方式$.post,$.get,$.getJSON
2014/03/28 Javascript
jQuery实现可用于博客的动态滑动菜单
2015/03/09 Javascript
JS基于cookie实现来宾统计记录访客信息的方法
2015/08/04 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
2015/09/27 Javascript
bootstrap-treeview自定义双击事件实现方法
2016/01/09 Javascript
聊一聊JS中的prototype
2016/09/29 Javascript
Angular.JS学习之依赖注入$injector详析
2016/10/20 Javascript
vue实现element-ui对话框可拖拽功能
2018/08/17 Javascript
vue.js实现带日期星期的数字时钟功能示例
2018/08/28 Javascript
vue文件运行的方法教学
2019/02/12 Javascript
Vue中遍历数组的新方法实例详解
2019/07/21 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
2019/08/27 Javascript
vue封装可复用组件confirm,并绑定在vue原型上的示例
2019/10/31 Javascript
Vue+ElementUI 中级联选择器Bug问题的解决
2020/07/31 Javascript
基于vue中的scoped坑点解说
2020/09/04 Javascript
基于jQuery拖拽事件的封装
2020/11/29 jQuery
[57:09]DOTA2-DPC中国联赛 正赛 Phoenix vs Dynasty BO3 第一场 1月26日
2021/03/11 DOTA
python局部赋值的规则
2013/03/07 Python
python anaconda 安装 环境变量 升级 以及特殊库安装的方法
2017/06/21 Python
Python清空文件并替换内容的实例
2018/10/22 Python
使用Python进行防病毒免杀解析
2019/12/13 Python
pycharm 快速解决python代码冲突的问题
2021/01/15 Python
Asics日本官网:鬼冢八喜郎创立的跑鞋运动品牌
2017/10/18 全球购物
中东地区为妈妈们提供一切的头号购物目的地:Sprii
2018/05/06 全球购物
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
售后服务承诺书
2014/03/26 职场文书
党的群众路线教育实践活动个人对照检查材料范文
2014/09/25 职场文书
2015年人力资源工作总结
2015/04/08 职场文书