(原)关于APNs和Provider
(自iOS开发文档"Local and Push Notification Programming Guide"里与iOS相关的部分翻译)
-----------------------------------------▲客户端处理------------------------------------------
建议每次程序启动的时候都调用registerForRemoteNotificationTypes来重新获取设备相关的token,而不要缓存token.
这是因为,如果用户重装了iOS或者用户换了设备并且恢复程序备份到一个新的设备,都将导致这个token值不一样。
当iOS收到远程消息时,
如果应用程序isn't running, iOS会处理这个消息,比如弹出一个框、在应用程序的icon上显示红色数字。
然后如果用户通过点击弹框进入程序,iOS会启动程序并调用application:didFinishLaunchingWithOptions并且拿远程消息的payload进行传参.
如果用户直接点击app icon进入程序,iOS会启动程序并同样调用application:didFinishLaunchingWithOptions,但是传参将不会有远程消息的任何信息。
如果应用程序is running in the foreground,就会调用application:didReceiveRemoteNotification.
如果应用程序is running in the background, 同样弹框,然后如果通过弹框进入程序,就会调用application:didReceiveRemoteNotification.
----------------------------------------------▲APNs----------------------------------------------
IOS设备会持久连接APNs以接受远程消息。
provider发送消息到APNs,然后APNs再发送到目标IOS设备。(这个传输是单向的。)
这个消息的内容含两部分:设备token和payload.
反馈服务--
有时候APNs发送消息到某设备(token)某程序(bundle identifier)但是该设备并没有这个程序,多次这种情况之后,APNs会通知provider,通过其连接的一个反馈服务(a feedback service)。
反馈服务为每一个程序维护了一个失效设备列表,provider应该获取这个列表从而停止向APNs发送以这些设备为目的地的某程序的远程消息。
APNs的安全架构--
provider需要一个有效证书才能和APNs连接(这个证书有目标程序的Bundle identifier信息)。
与APNs连接后,provider向APNs发送的消息带有设备token(由目标程序连接provider然后发来token),APNs以此找到目标设备,然后看目标设备里的目标程序有接受推送的证书,APNs以此验证给目标设备的目标程序发送的消息是合法的。
注意:远程消息是不可靠的。
----------------------------------------▲Provider-------------------------------------------
Payload--
最多256bytes。
本地化alert:
eg:"alert" : {"loc-key":"GAME_PLAY_REQUEST_FORMAT","loc-args":["Jenna","Frank"]},
程序包里面的本地化字符串如下:
"GAME_PLAY_REQUEST_FORMAT" = "%@ and %@ have invited you to play Monopoly";
这样,最后显示alert的字符串就是:
"Jenna and Frank have invited you to play Monopoly"
一个JSON Payload的完整例子(为了性能,建议去掉空白字符)
{
"aps" :
{
"alert" : "Message received from Bob",
"badge" : 5,
"sound" : "bingbong.aiff"
},
"myCustomData" : ["bang", "bang、bang、bang"],
"myCustomData2": 42
}
----------------------------------------▲部署-------------------------------------------
要部署provider端client/server程序,需要来自苹果的SSL证书。下称provider证书。
provider证书对应于特定的iOS Application(Bundle identifier)。
同时,provider证书分为开发测试和产品两种版本,对应于两种APNs环境:
Sandbox(Development) :可用模拟器测试。地址是gateway.sandbox.push.apple.com: TCP 2195
Production(Distribution):gateway.push.apple.com: TCP 2195
同时,provision profile也对应了两个版本:Development和Distribution.(The Distribution provision profile is a requirement for submitting your application to the App Store.)
可以在xcode里看iOS application所处何环境:看编译选项里的code-signing identity,如果是"iPhone Developer:Firstname Lastname"证书与provisioning profile匹配成对,说明是sandbox环境。如果是"iPhone Distribution:Companyname"证书与provision profile匹配成对,说明是production环境。根据release和debug分别配置code-signing identity选项的证书将会是一个好主意。
注意:尽管SSL证书(即provider证书)没有放到iOS application的providion profile里,但是ios application是否支持远程消息推送依然取决于profile,因为profile内含开发者证书、设备ID、application ID(Bundle identifier)、"是否支持推送"(在苹果开发者网站上配置证书的时候配置的)等信息。(The provisioning profile is a collection of assets that associates developers of an application and their devices with an authorized development team and enables those devices to be used for testing.The profile contains certificates,device identifiers,the application's bundle ID,and all entitlement,including <aps-environment>.)
以文本方式打开*.mobileprovision,会看到里面类似xml格式,其中<key>Entitlements</key>里包含了<key>aps-environment</key>,说明支持远程消息推送,<key>aps-environment</key>下面的<string>说明是调试版本还是发布版本(对应于Sandbox环境和Production环境)。
{/// add by U:
注意这个profile必须是和我们的Bundle identifier关联起来的,不可以全匹配(通配符 ID 不能用于推送通知服务。)。所以可能需要重新create profile。然后把这个profile下下来双击使安装到~/Library/MobileDevice/Provisioning\ Profiles目录下。
这是还不行,要想ios程序成功注册远程消息,还需要在xcode4工程里配置:选中TARGET,Summary,下面的Entitlements勾选上"Enable Entitlements"。然后会发现工程里新建了一个${PRODUCT_NAME}.entitlements的文件,用文本方式打开,在键值对里面添加:
<key>aps-environment</key>
<string>development</string> 《——如果是发布版那就是production
<key>get-task-allow</key> 《——这个键是说让不让别的程序控制自己(即:让不让xcode来debug程序)。
<true/> 《——理论上这个值得和对应的profile里的一致。发布版一般应该是false(不让别的程序控制自己——即不能xcode联调了)。
}
●安装证书到服务端(这段是直接翻译的文档的,本文下面的“摘录自哪的” 这一章节才是实际搞出来的~)
你应该安装SSL证书和私匙到你的provider程序运行的服务器上。
步骤如下:
0.安装该证书到mac电脑的钥匙串。
1.打开钥匙串,在左侧面板上点击我的证书栏。
2.找到这个SSL证书,展开会看到证书和私匙。
3.我们选中证书和私匙,然后导出为"个人信息交换文件"--即扩展名为p12的文件。
4.provider服务器程序最好用Ruby和Perl这类语言,可以方便的处理"个人信息交换文件"里的证书。mac下打开终端输入以下命令以把证书转换为这类语言乐于交流的格式:
openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes
5.把这pem文件拷到服务器上并安装到某个适当的位置。
----------------------------------------▲Provider与APNs连接----------------------------------------
●连接APNs之前provider需要具备什么
APNs提供的连接接口是二进制的、streaming TCP socket、异步 的。
Production环境是通过gateway.push.apple.com:2195,Development环境是gateway.sandbox.push.apple.com:2195。
Provider可以建立多个与APNs的连接。每个都得用TLS(or SSL)来建立安全通道,需要用到SSL证书(就是上面提到的provider连接APNs要用到的SSL证书)。
----------------------
Note 要建立与APNs的TLS会话,需要在provider服务器上安装Entrust Secure CA根证书。Moa OS X是默认已安装的,其他系统的话,可以没有安装,可以从Entrust SSL Certificates的网站http://www.entrust.net/下载安装根证书。
----------------------
●发送消息的二进制接口和消息的数据包格式
消息须是网络字节顺序(即大尾顺序),消息里面的payload部分不可以超过256字节,且不得以'\0'结尾。
消息格式见"The Binary Interface and Notification Formats"章节。
●The Feedback Service
feedback service包含了这样的列表:某iOS应用程序对应的"设备"("设备"用二进制格式的设备token来标识)。--这些设备是由于各种原因而不能接收APNs发来的消息。
Provider应该定期查询这个列表,并且作出对应处理,如:停止向这些的设备发送消息。
provider访问feedback server通过一个与发送消息类似的二进制接口。
Production环境通过feedback.push.apple.com:2196来建立连接,Development通过feedback.sandbox.push.apple.com:2196。
feedback service和发送消息是不同的服务接口(但都属于APNs),他的连接方式和发送消息是一样的。也要通过证书建立SSL连接,连接后你不需要发送任何命令,直接开始读取流一直读完为止,然后provider要解析读到的数据。
数据是由多个这样的格式组成的:
| 四字节时间 | 2字节的token 长度 | 32字节的设备token |
关于"四字节时间":Provider需要判断对应设备的这个iOS应用程序有没有在该时间之后重新像provider发送注册推送消息所获得的设备token。如果没有,就认为该设备失效了,需停止向该设备发送消息。如果有,那就是这个设备失效过,但是现在又有效了,只是feedback service还没来得及刷新列表。
-----------------------------摘录自哪的------------------------
在Mac上生成 Apple推送通知SSL许可证:
登录到 iPhone Developer Connection Portal 并点击 App IDs
创建一个不使用通配符的 App ID 。通配符 ID 不能用于推送通知服务。例如,我们的iPhone程序ID像这样: AB123346CD.com.serverdensity.iphone
点击App ID旁的"Configure",然后按下按钮生产 推送通知许可证。根据"向导"指导的步骤生成一个签名并上传,最后下载生成的许可证。此步骤在 Apple文档中 也有谈到。
通过双击.cer文件将你的 aps_developer_identity.cer 引入Keychain中。
在Mac上启动 Keychain助手,然后在login keychain中选择 Certificates分类。你将看到一个可扩展选项"Apple Development Push Services"
扩展此选项然后右击"Apple Development Push Services" > Export "Apple Development Push Services ID123"。保存为 apns-dev-cert.p12 文件。
扩展"Apple Development Push Services" 对"Private Key"做同样操作,保存为 apns-dev-key.p12 文件。
需要通过终端命令将这些文件转换为PEM格式:
openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
如果你想要移除密码,要么在导出/转换时不要设定或者执行:
openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem
最后,你需要将键和许可文件合成为apns-dev.pem文件,此文件在连接到APNS时需要使用:
cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem
-----------------------------linshi------------------------------
▲APNs客户端及部署网文:
http://www.cnblogs.com/chenjunbiao/archive/2011/07/28/2119259.html
http://www.cnblogs.com/zhw511006/archive/2010/09/01/1815089.html
▲APNs的开源代码:
https://github.com/bnigro/apn_on_rails3
https://github.com/Redth/APNS-Sharp
▲linux网络编程之SSL
http://wenku.baidu.com/view/5268a995dd88d0d233d46a80.html