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 相关文章推荐
python安装mysql-python简明笔记(ubuntu环境)
Jun 25 Python
Python 查看文件的读写权限方法
Jan 23 Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
Feb 26 Python
python UDP(udp)协议发送和接收的实例
Jul 22 Python
Django中的静态文件管理过程解析
Aug 01 Python
python使用 cx_Oracle 模块进行查询操作示例
Nov 28 Python
Python内置类型性能分析过程实例
Jan 29 Python
python实现图像拼接功能
Mar 23 Python
python switch 实现多分支选择功能
Dec 21 Python
python之openpyxl模块的安装和基本用法(excel管理)
Feb 03 Python
Django cookie和session的应用场景及如何使用
Apr 29 Python
Python实现byte转integer
Jun 03 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
php与php MySQL 之间的关系
2009/07/17 PHP
PHP swfupload图片上传的实例代码
2013/09/30 PHP
PHP中Fatal error session_start()错误解决步骤
2014/08/05 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
js类中获取外部函数名的方法与代码
2007/09/12 Javascript
JS+ACTIVEX实现网页选择本地目录路径对话框
2013/03/18 Javascript
JQUERY对单选框(radio)操作的小例子
2013/04/25 Javascript
js插件方式打开pdf文件(浏览器pdf插件分享)
2013/12/20 Javascript
jquery的attr方法禁用表单元素禁用输入内容
2014/06/23 Javascript
JQuery EasyUI 加载两次url的原因分析及解决方案
2014/08/18 Javascript
详解jQuery中的元素的属性和相关操作
2015/08/14 Javascript
js输出数据精确到小数点后n位代码
2016/07/02 Javascript
Ionic + Angular.js实现验证码倒计时功能的方法
2017/06/12 Javascript
node.js 发布订阅模式的实例
2017/09/10 Javascript
基于JS实现html中placeholder属性提示文字效果示例
2018/04/19 Javascript
layui中table表头样式修改方法
2018/08/15 Javascript
Layui带搜索的下拉框的使用以及动态数据绑定方法
2019/09/28 Javascript
微信小程序实现音频文件播放进度的实例代码
2020/03/02 Javascript
解决VueCil代理本地proxytable无效报错404的问题
2020/11/07 Javascript
[56:38]DOTA2-DPC中国联赛正赛Aster vs Magma BO3 第一场 3月5日
2021/03/11 DOTA
python enumerate函数的使用方法总结
2017/11/15 Python
python使用threading获取线程函数返回值的实现方法
2017/11/15 Python
python 日志增量抓取实现方法
2018/04/28 Python
python TF-IDF算法实现文本关键词提取
2019/05/29 Python
详解python调用cmd命令三种方法
2019/07/08 Python
django 邮件发送模块smtp使用详解
2019/07/22 Python
Python3直接爬取图片URL并保存示例
2019/12/18 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
2020/04/08 Python
美赞臣新加坡官方旗舰店:Enfagrow新加坡
2019/05/15 全球购物
教师自荐书
2013/10/08 职场文书
旺仔牛奶广告词
2014/03/20 职场文书
党员承诺书格式
2014/05/21 职场文书
交通安全标语
2014/06/06 职场文书
小学教师读书活动总结
2014/07/08 职场文书
2014市府办领导班子“四风问题”对照检查材料思想汇报
2014/09/24 职场文书