惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
A
Arctic Wolf
K
Kaspersky official blog
V
Vulnerabilities – Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Simon Willison's Weblog
Simon Willison's Weblog
L
LINUX DO - 热门话题
MongoDB | Blog
MongoDB | Blog
T
Threat Research - Cisco Blogs
D
Docker
爱范儿
爱范儿
T
Tenable Blog
C
Check Point Blog
B
Blog
C
Cisco Blogs
Vercel News
Vercel News
The Cloudflare Blog
T
Threatpost
NISL@THU
NISL@THU
T
Tor Project blog
V2EX - 技术
V2EX - 技术
P
Palo Alto Networks Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tailwind CSS Blog
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
SecWiki News
SecWiki News
博客园 - 司徒正美
S
Security @ Cisco Blogs
GbyAI
GbyAI
S
Secure Thoughts
Microsoft Security Blog
Microsoft Security Blog
The Register - Security
The Register - Security
Recorded Future
Recorded Future
Cloudbric
Cloudbric
Webroot Blog
Webroot Blog
N
News and Events Feed by Topic
Y
Y Combinator Blog
博客园_首页
T
Troy Hunt's Blog
The Hacker News
The Hacker News
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
U
Unit 42
AWS News Blog
AWS News Blog
PCI Perspectives
PCI Perspectives
V
Visual Studio Blog
博客园 - 聂微东
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell

犀利豆的博客

《SRE google 运维解密》读书笔记 (六) 《SRE google 运维解密》读书笔记 (五) 《SRE google 运维解密》读书笔记 (四) 《SRE google 运维解密》读书笔记 (三) 《SRE google 运维解密》读书笔记 (二) 《SRE google 运维解密》读书笔记 (一) 2021 总结 终于有一个 Java 可以用的微信机器人了 Vertx入门到实战—实现钉钉机器人内网穿透代理 钉钉机器人回调内网穿透代理--使用篇 周末补习(一)trie 树 那些有趣的代码(三)--勤俭持家的 ArrayList 那些有趣的代码(二)--偏不听父母话的 Tomcat 类加载器 那些有趣的代码(一)--有点萌的 Tomcat 的线程池 从需求第三定律说起--为什么知乎的回答质量下降了 如何利用 Spring Hibernate 高级特性设计实现一个权限系统 居然有人能忘记吃饭?写个微信机器人提醒他 我的2018年总结 从 LongAdder 中窥见并发组件的设计思路 徒手撸框架--实现 RPC 远程调用 我的写作工具链 Java 渲染 docx 文件,并生成 pdf 加水印 撸码的福音--变量名生成器的实现 Raft 协议学习笔记 dubbo 源码学习(一)开篇 Redis 命令的执行过程 Redis 中的事件驱动模型 Redis 数据库、键过期的实现 Redis 的基础数据结构(三)对象 Redis 的基础数据结构(二) 整数集合、跳跃表、压缩列表 Redis 的基础数据结构(一) 可变字符串、链表、字典 线程池 execute() 的工作逻辑 JAVA 中的 CAS 徒手撸框架--高并发环境下的请求合并 徒手撸框架--实现Aop 徒手撸框架--实现IoC 2017个人总结 最近遇到的几个问题集合 Redis RedLock 完美的分布式锁么? JAVA 8入门(二)流 JAVA 8入门(一)Lambda表达式 有道 Alfred Workflow 威力加强版 Kafka实现原理笔记 《交易系统:更新与跨越》读后笔记 Future研究 Hystrix入门研究 Redis实现分布式锁
Netty-Apns接入实现
Zhengxin Diao · 2017-10-24 · via 犀利豆的博客

极光推送免费版每分钟600次的请求限制实在是把我恶心坏了,考虑到现在我们 Android 的推送已经全量接入了小米,所以接下来就是要把 iOS 的推送直接接入 APNS 这样就可以彻底摆脱极光的推送。不再受这个600次/分钟的限制了。APNS使用 HTTP2 协议进行通信所以自然就想到了使用Netty作为网络框架,进行开发。下面逐个给大家介绍使用 Netty 接入 APNS 的注意事项和接入的时候踩到的坑。

APNS 是 Apple 提供的推送服务。官方文档
下面说一说自己对接入APNS的时候遇到的坑:

  1. APNS 使用 HTTP/2 协议通信,必须使用 TLS 1.2 或以上的加密方式通信,如果使用JDK提供的加密方法,如果使用 JDK7 ,需要对 JVM 的启动参数进行设置,另一个比较简单的解决方法,就是使用 JDK 8 。JDK 8 就能很好的解决加密的问题,或者调用系统的Openssl 进行加解密。具体看大家的线上环境决定。
  2. 在开发的时候还遇到一个比较奇葩的问题,就是使用开发证书可以推送到达,但是切换到线上后发现怎么推送都不能到达,后来仔细读了官方文档,发现在请求头中有一个 apns-topic 字段,如果你的推送证书中包括了不止一个应用,这个字段就是一个必填字段,且为应用的 bundle ID
  3. 由于使用了 HTTP/2 协议,APPLE 推荐尽量复用链接,因为使用了 TLS 加密,每次建立连接的握手会消耗大量的时间。同时还可以使用多个连接提升推送的效率,所以之后的实现中,我使用 Common pool2 作为连接池来提高推送的效率。可以使用 PING 来检查连接是否有效。所以在实现的时候使用了 Netty 的 IdleStateEvent 来检查连接。

代码的具体实现:

首先看看代码的结构:
![屏幕快照 2017-05-14 下午11.10.10](http://7u2r32.com1.z0.glb.clouddn.com/屏幕快照 2017-05-14 下午11.10.10.png)

Module 中的 Payload 和 PsuhsNotifcation 的是对 APNS 的数据结构的封装,具体可以参考 Apple 提供的文档
ApnsConfig 是对整个推送系统的相关设置,提供了一些默认参数。可以根据需要自己进行设置。
PingMessage 从名字就能看出,是对链接进行检测的 PING frame

下面着重介绍一下Service相关的实现思路。

具体实现

Netty 的 Client 的代码我参考了 Netty官方提供的 Example

  1. ApnsConnection 实现了 Connection 接口,主要负责维护和 APNS 的链接。
    ![屏幕快照 2017-05-14 下午11.20.37](http://7u2r32.com1.z0.glb.clouddn.com/屏幕快照 2017-05-14 下午11.20.37.png)

  2. 接池的实现:

链接池相关的代码主要在 ApnsConnectionPool 中。整个链接池的使用了 Commone Pool2作为底层实现,实现的时候主要参考了jedies的链接池的实现。

3.NettyApnsService 向外暴露了推送的接口。直接调用sendNotification()方法就能推送消息了。

![屏幕快照 2017-05-14 下午11.26.31](http://7u2r32.com1.z0.glb.clouddn.com/屏幕快照 2017-05-14 下午11.26.31.png)

总结

代码地址:https://github.com/diaozxin007/Netty-apns

欢迎大家拍砖指点。

看开源的代码是快速学习的方法,在整个项目中,参考了很多开源的工程的具体实现。希望对大家有所帮助。