移动互联网实战--Apple的APNS桩推送服务的实现(1)
前记:
相信大家在搞IOS推送服务的开发时, 会直接使用javapns api来简单实现, 调试也直连Apple的APNS服务(产品/测试版)来实现. 很少有人会写个APNS的桩服务, 事实也是如此. 只是当时我所面临的应用场景有些特殊, 为了测试服务的性能和调试功能方便, 特地写了APNS的桩服务(其实主要原因是当时的iphone测试机, 被小组长"霸占"占为己用, ⊙﹏⊙b汗). 在此写一篇关于APNS桩服务的文章, 以此纪念逝去的"青春", 也希望对读者有所帮助.
有些事情回想起来, 历历在目, 清晰异常, 仿佛发生在昨天. 犹记一年前, 开发IOS的APNS推送后端服务, 吐血三升...
本文侧重一些基础知识, 具体实现详见后一篇.
基础知识:
APNS(Apple Push Notification Service)协议, 用于解决通过APNS服务来实现往IPhone手机推送消息的基础需求.
其基本的流程如下所示:
服务端和客户端基础架构
二进制网络协议:
APNS的二进制协议设计,格外注重吞吐量. v1版本完全摒弃ack机制, 服务推送遇到异常, APNS服务器会直接断开连接. v2版本弱化ack机制, 只有错误的那个推送消息, 才会ack并携带出错信息(比如bad device token), 然后才断开连接.
1). v1版本的协议:
2). v2版本的协议
消息推送请求如下:
数据响应如下:
相关的错误码如下:
Status code |
Description |
---|---|
0 |
No errors encountered |
1 |
Processing error |
2 |
Missing device token |
3 |
Missing topic |
4 |
Missing payload |
5 |
Invalid token size |
6 |
Invalid topic size |
7 |
Invalid payload size |
8 |
Invalid token |
10 |
Shutdown |
255 |
None (unknown) |
Java SSL编程(JSSE):
JSSE的类体系如下所示:
评注: 来源于网络, 相关链接请点击. 抽取部分类定义简单介绍.
SSLContext: 安全套接字协议的实现, 也是SSLSocketFactory/SSLServerSocketFactory以及SSLEngine的工厂.
KeyStore: 标示密钥和证书的存储设施.
KeyManager: JSSE密钥管理器.
TrustManager: 信任管理器.
X590TrustedManager: TrustManager的子接口,管理X509证书,验证远程安全套接字.
简单的样列代码如下:
SSLContext ctx = SSLContext.getInstance("SSL"); KeyManagerFactory kmf = KeyManagerFactory .getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load("<KeyStorePath>", "<KeyPassword>".toCharArray()); kmf.init(ks, "<KeyPassword>".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType()); tks.load("<TrustKeyStorePath>", "<TrustKeyPasswod>".toCharArray()); tmf.init(tks); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); // *) 构建ServerSocket, 用于服务端连接 ctx.getServerSocketFactory().createServerSocket(); // *) 构建Socket, 用于客户端连接 ctx.getSocketFactory().createSocket();
证书管理:
基本概念:
SSL的连接创建引入了证书和信任仓库的概念, 其分别委托于KeyMananger, TrustManager进行管理.
认证方式:
1). 单向认证: SSL握手过程中, 只需要单方认证即可.
2). 双向认证: SSL握手过程中, 双方需要各自认证.
证书的构建过程(单向认证, 服务端举例)
1). 服务端构建证书
keytool -genkey -v -alias ssl-server -keyalg RSA -keystore ./server_ks -storepass server -keypass 123456
2). 导出服务端证书
keytool -export -alias ssl-server -keystore ./server_ks -file server_key.cer
3). 导入到客户端的信任证书仓库
keytool -import -trustcacerts -alias ssl-server -file ./server_key.cer -keystore ./client_ks
单向认证的证书信任关系就添加完成, 双向认证只需要把客户端的导出证书导入到服务端的信任仓库即可.
密钥库格式/标准:
JKS和PKCS#12都是比较常用的两种密钥库格式/标准. JKS文件(通常为*.jks或*.keystore,扩展名无关)可以通过Java原生工具——KeyTool生成; 而PKCS#12文件(通常为*.p12或*.pfx,意味个人信息交换文件), 则是通过更为常用的OpenSSL工具产生. 当然, 这两者之间是可以通过导入/导出的方式进行转换的! 当然, 这种转换需要通过KeyTool工具进行! APNS的证书格式采用的P12格式, 即PKCS#12格式标准.
总结:
这边主要讲述APNS的基本概念和知识, 以及JSSE编程相关的一些类和证书/信任机制. 并没有对APNS桩实现进行需求分析和实现的介绍, 后一篇文章将详细讲解, 敬请期待.
posted on 2014-08-25 12:31 mumuxinfei 阅读(1112) 评论(0) 编辑 收藏 举报