推送 方法2

手把手教你配置苹果APNS推送服务php


 

1. 什么是推送通知

 

消息通知分本地通知和远程推送通知,是没有运行在前台的应用程序可让它们的用户得到相关消息通知的方式。消息通知多是一条消息,即将发生的日历 事件,或远程服务器的新数据。当被操做系统显示时,本地通知和推送通知看起来同样。它们能够显示一个警告信息或在应用程序的图标上面显示一个徽标。它们也 能够在警告窗或徽标显示时播放一段声音。推送通知是在 iOS 3.0 和 Mac OS X v7.0 以后引入的。本地通知是在 iOS 4.0 以后引入的。它们都不支持 Mac OS X,当用户被通知相应的应用程序有消息,事件,或其余数据时,他们能够启动该应用程序并查看详情。他们也能够选择忽略通知,此时应用程序没有被激活。html

本地通知和推送通知为不一样的需求而设计的。本地通知是本地 iPhone、iPad、或iPod touch 上面的应用发起的。相反推送通知(又称远程通知)是从其余设备上面到达的。它来自一个远程设备——应用程序的提供者——并在有新的消息须要查看或新的数据 须要下载的时候被推送到本地设备上面的应用,常见的本地通知像iphone的日历,微信或者qq这些都是本地推送,好比还安装了优酷,qq视频这些软件, 容许推送后,天天会给你发些新的视频消息,这些就是远程推送。java

 

2. 什么是APNS?

 

苹果推送通知服务(APNs)是推送通知的网关,iPhone ipad 对于应用程序在后台运行有诸多限制,考虑到手机电池电量,应用不容许在后台进行过多的操做。所以,当用户切换到其余程序后,原先的程序没法保持运行状态。 对于那些须要保持持续链接状态的应用程序(好比社区网络应用),将不能收到实时的信息。推送是解决轮询所形成的流量消耗和电量消耗的一个比较好的解决方案mysql

为解决这一限制,苹果推出了APNs(苹果推送通知服务 Apple Push Notification services)。APNs 容许设备与苹果的推送通知服务器保持常链接状态。当你想发送一个推送通知给某个用户的iPhone上的应用程序时,你可使用 APNs 发送一个推送消息给目标设备上已安装的某个应用程序。ios

苹果的推送服务APNs基本原理简单来讲就是苹果利用本身专门的推送服务器(APNs)接收来自咱们本身应用服务器的须要被推送的信息,而后推送到 指定的iOS设备上,而后由设备通知到咱们的应用程序,设备以通知或者声音的形式通知用户有新的消息。推送的前提是装有咱们应用的设备须要向APNs服务 器注册,注册成功后APNs服务器会返给咱们一个device_token,拿到这个token后咱们将这个token发给咱们本身的应用服务器,当有需 要被推送的消息时,咱们的应用服务器会将消息按指定的格式打包,而后结合设备的device_token一并发给APNs服务器,因为咱们的应用和 APNs维持一个基于TCP的长链接,APNs将新消息推送到咱们设备上,而后在屏幕上显示出新消息来。git

顺便说下安卓的推送,Android消息推送采用MQTT协议,服务器端采用mosquito+PhpMQTTClient,有兴趣的同窗能够看看github

mosquito:http://mosquitto.org/web

PhpMQTTClient   :https://github.com/tokudu/PhpMQTTClientsql

 

3. 推送流程

 

3.1 获取设备device_token阶段

整个过程基本就这样,下面咱们看一下设备注册APNs的流程图:数据库

上图完成了以下步骤:

1.Device链接APNs服务器并携带设备序列号

2.链接成功,APNs通过打包和处理产生device_token并返回给注册的Device

3.Device携带获取的device_token向咱们本身的应用服务器注册

4.完成须要被推送的Device在APNs服务器和咱们本身的应用服务器注册

执行顺序以下所示:

这里要提到的一点是,咱们的设备和APNS服务器之间的通信是基于SSL协议的TCP流通信,两者之间维持一个长链接,当从APNS服务器注册成功 后,必定要将device_token发送给咱们的应用服务器,由于在推送过程当中,首相是由咱们的应用服务器(上图中Provider)将须要推送的消息 结合device_token按指定格式(后面会提到)打包而后发送给APNS服务器,而后由APNS服务器推送给咱们的设备。

3.2 消息推送过程

好了,注册设备的过程完成了,接下来就是如何推送了:

推送的过程通过以下步骤:

1.首先,安装了具备推送功能的应用,咱们的设备在有网络的状况下会链接苹果推送服务器,链接过程当中,APNS会验证device_token,链接成功后维持一个长链接;

2.Provider(咱们本身的服务器)收到须要被推送的消息并结合被推送设备的device_token一块儿打包发送给APNS服务器;

3.APNS服务器将推送信息推送给指定device_token的设备;

4.设备收到推送消息后通知咱们的应用程序并显示和提示用户(声音、弹出框)

3.3 完整流程介绍

比较直观的流程参照下图:

 

 

  1. 应用启用推送通知功能,须要用户确认;
  2. 应用收到设备识别ID(device token),至关于接收推送通知的地址;
  3. 应用将设备识别ID发送到你开发的服务器;
  4. 当有推送通知的须要时,你就能够经过你开发的服务组件发送信息到苹果的服务器上;
  5. 苹果推送通知服务将信息推送到用户的设备上。

上图显示了咱们的应用服务器将消息推送到咱们的App的完整路径,其实真正完成推送的是APNS服务器,咱们本身的应用服务器只是将须要推送的消息告诉苹果服务器,至于如何维护消息队列或如何保证消息能被推送到指定的设备上,这些都由苹果APNS给咱们作完了

4. Push机制类型

 

四种:徽章、提示框、声音和横幅,具体表现形式以下图

Push机制的4个组件

Provider

APNS

iPhone设备

Client App

其中APNS(Apple Push Notification Service)是由苹果提供的消息推送服务中心,全部的消息都经由这里转发给相应的设备

 

 

5. 正式开工

5.1 准备工做

你得有台ios设备,iphone,ipad

 5.1.2 为推送通知获取受权

为了给提供者这边开发和配置推送通知,你必须从开发者中心(即苹果官网 DevCenter)取得 SSL 受权证书。每一个受权证书限制必须对应一个单独的应用,由应用的Bundle ID 标识。并且该受权证书也被限制用于如下两个环境之一,沙箱环境(用于开发和测试)和生产环境。这些环境都拥有它本身的 IP 地址,并且须要它们本身的受权证书。你必须同时得到这些环境的的配置文件(即 Provisioning profiles)。

5.1.3 提供者和APNs之间经过二进制接口通讯

二进制接口是异步的,并且它使用 TCP 方式经过 sock 链接把二进制内容的推送通知发送给 APNs。沙箱和生产环境都有本身独立的接口,每一个都有它本身的地址和端口。对于每一个接口,你须要使用 TLS(或 SSL)和已经拿到的 SSL 受权证书来创建一条到 APNs 的安全通讯通道。提供者把推送通知打包并经过该通道发送给 APNs。APNs 包含了一个反馈服务,它负责维护每一个应用的传递通知失败的设备列表(即APNs 当前没法把推送通知传递到这些设备上面的对应的应用)。提供者应该周期性的链接到反馈服务来查看推送失败的设备以便它能够把以前失败的通知重复发送过
去。

开发状态服务器地址 gateway.sandbox.push.apple.com 2195

产品状态服务器地址 gateway.push.apple.com 2195

Development和Production两个版本对应的apns device token是不一样的,前者是develop的mobileprovision下获取的。后者是production的mobileprovision获取的。
Development和Production两个版本能够共用一个App ID(不推荐。共用时每次调试前都要删除设备上的app,从新打包生成。并且公用appid会常常抓狂,早上行,下午就不行了。因此不推荐),可是不能共 用一个mobileprovision,因此要单独生成Distribution的证书供production版本使用。
注:Distribution的版本是没法在设备上debug调试的!
Development和Production两个版本的code sign是不一样的,前者是iPhone Developer,后者是iPhone Distribution。注意不能搞错。

不管是Development Push SSLCertificate仍是Production Push SSL Certificate 都有过时时间的。Development Push SSL Certificate有效期大概四个月左右,而ProductionPush SSL Certificate的有效期是一年。须要注意在过时以前生成新的证书,以避免影响使用。

 

5.2 证书生成

 

5.2.1 过程简介

先概述下大体过程,而后下面会截图给出详细的步骤

在Mac上生成 Apple推送通知SSL许可证:
 1. 登陆到 apple Developer Connection Portal 并点击 App IDs
 2. 建立一个不使用通配符的 App ID 。通配符 ID 不能用于推送通知服务。例如,咱们的iPhone程序ID像这样:54im.com.PushChat
 3. 点击App ID旁的“Configure”,而后按下按钮生产 推送通知许可证。根据“向导”指导的步骤生成一个签名并上传,最后下载生成的许可证。
 4. 经过双击.cer文件将你的 aps_developer_identity.cer 引入Keychain中。
 5. 在Mac上启动 Keychain助手,而后在login keychain中选择 Certificates分类。你将看到一个可扩展选项“Apple Development Push Servicescom.54im.PushChat”
 6. 扩展此选项而后右击“Apple Development Push Services” > Export “Apple Development Push Services:com.54im.PushChat”。保存为 PushChat_cert.p12 文件。
 7. 扩展“Apple Development Push Services” 对“Private Key”作一样操做,保存为 PushChat_key.p12 文件。
 8. 须要经过终端命令将这些文件转换为PEM格式:
openssl pkcs12 -clcerts -nokeys -out cert.pem -in PushChat_cert.p12
 9. 转换获得key的pem:
openssl pkcs12 -nocerts -out key.pem -in PushChat_key.p12
 10. 若是你想要移除密码,要么在导出/转换时不要设定或者执行:
openssl rsa -in key.pem -out key.unencrypted.pem
 11. 最后,你须要将键和许可文件合成为apns-dev.pem文件,此文件在链接到APNS时须要使用:
cat apns-dev-cert.pem key.unencrypted.pem > ck.pem

5.2.2 配置详解

 1. 建立APPID

首先登录咱们的Apple Developer后台为将要使用推送服务的App新建一个App ID,以下图,点击新建后输入基本信息

 

我把要改的地方截图下来了,高手勿笑哦,屌丝第一次用mac,也是第一次进苹果开发者后台。

APPID建立好后,咱们点编辑刚刚生成好的APPID,生成下development证书,生产状况下用 Production证书

 

 

建立正式过程当中,要求上传一张Certificate Signing Request 证书请求签名文件

 

2. 生成证书请求文件

这个请求文件在本身的mac上生成

输入证书信息

 

3. 生成PUSH证书

还记得刚刚苹果开发者那里要上传的证书不,将生成好的这个.certSigningRequest证书上传上去,

下载aps_development.cer这个证书到mac上,若是是发布版的推送证书,就为aps_production.cer。而后双击该 证书,将推送证书安装到咱们的Mac机器上,安装成功后会看到以下界面(若是是发布版,则证书的Development部分显示的是 Production)

 

须要为certificate和它之下的private key各自export出一个.p12文件。(会出现设置密码过程)

4. 导出公钥

导出私钥

 

5. key转换

须要将上面的2个.p12文件转成.pem格式:

openssl pkcs12 -clcerts -nokeys -out cert.pem -in Push_Chat_cert.p12
openssl pkcs12 -nocerts -out key.pem -in Push_Chat_cert_key.p12

若是须要对key不进行加密
openssl rsa -in key.pem -out key.unencrypted.pem

而后就能够 合并两个.pem文件, 这个ck.pem就是服务端须要的证书了
cat cert.pem key.unencrypted.pem > apns-dev.pem

建立 Provisioning Profile

 

5.3 建立 provisioning profile

 

接下来,须要建立 provisioning profile 以便容许应用程序安装到真实设备上。

 

将该prifiles文件下载下来,名字是PushChat.mobileprovision,其实不用下载,xcode里面会根据你的项目id自动去拉对于的这个文件。

在制做测试demo前咱们先了解下开源的一个应用 easyapns,或者你也能够写demo,主要就是收集DeviceToken

啥是Easy APNS

Easy APNS 是一个用来管理苹果推送通知的PHP脚本。若是你对苹果推送通知后端部分比较感兴趣,而恰巧你有熟悉PHP,那么Easy APNS是你工具箱中必须的工 具。Easy APNS彻底开源,而且设置很是简单。经过使用免费的、开源的PHP脚本,Easy APNS为开发者提供了一种很直观的能够用来控制整个 推送通知后端部分的方式。

项目官网:http://www.easyapns.com/

github地址:https://github.com/manifestinteractive/easyapns

github里面有这几个目录

delegate 将这里面代码添加到新建项目的 AppDelegate.m中

php 将文件放在一个能够访问的web目录下(要有php+mysql环境)

sql 将该目录sql导入到数据库

 

6. 客户端制做

开始制做咱们的客户端

在代码中加入如下代码

而且修改里面的push服务器地址

如今能够把项目编译到iphone或者ipad上面了,注意项目 General中team配置。


而后插上本身的iphone或者ipad,就能够点build按钮了,这时屏幕上会弹出一个警告框,是否容许消息推送,相似于

用户同于消息推送后,也能够自行再关闭掉,也能够自行调整通知方式

7. php服务器端配置

 

数据库导入

create database pushchat DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

mysql -h 127.0.0.1 -uroot -p –databse pushchat<apns.sql

修改apns.php 和samples.php配置文件

$db = new DbConnect(‘localhost’, ‘root’, ’54im.com’, ‘pushchat’);

而后单独修改class目录下class_APNS.php的证书和日志路径

private $DEVELOPMENT = ‘sandbox’

private $logPath = ‘/usr/local/apns/apns.log

private $sandboxCertificate = ‘/usr/local/apns/ck.pem

固然你的证书也必须放到这个目录下(就是以前合并的那个证书)

在手机上打开咱们安装的那个PushChat应用,而后数据库中就有手机发送过来的

8. 测试

 

消息发送测试,在服务器上执行samples.php 就能够

php -f samples.php

备注:

服务器端,若是是php的,那必须使用.pem的证书,若是是java的,那必须使用.p12的证书。(极可能还须要双击证书进行安装!)
服务器端发出的json包是有大小限制的,最大256字节,包括自定义字典集。
aps中的alert字符串里是能够添加”\n”作换行的。
json包中除了alert,badge,sound以外,仍是是能够自定值的。

额外的自定义值:
$payload[‘aps’] = array(‘alert’ => ‘This is the alert text’, ‘badge’ => 1, ‘sound’ => ‘default’);
$payload[‘server’] = array(‘serverId’ => $serverId, ‘name’ => $name);
$output = json_encode($payload);
当用户按下“View”后,自定义server值将被传递到设备中的程序。JSON 值以下:
{
“aps” :
{ “alert” :
{
“action-loc-key” : “显示” ,
“body” : “This is the alert text”
},
“badge” : 1,
“sound” : “default” },
“server” : { “serverId” : 1, “name” : “Server name”)
}
256字节的限制适用于整个payload,包括自定义字典集。

 

IOS7以前,苹果对于一个设备上的多个APP,生成相同的DeviceToken。
IOS7以及以后,苹果对于一个设备上的多个APP,生成不一样的DeviceToken。
这种新改变致使APNS上建立了一张新老token的映射表,若是你一直用老的token,那没问题,可是,一旦服务器使用新的DeviceToken,映射表中的记录就会被删除,这意味着,老的DeviceToken就不能用了,必然发送失败。
待验证:IOS5和IOS6,APP永远能够获取DeviceToken,除此以外的系统,若是用户拒绝了,或者关闭了推送,那么没法获取DeviceToken,走失败回调。

 

 

8. 附录:

8.1 JSON示例

如下通知负载的示例举例说明了表 3-1 所列举的属性。名为”acme”的属性是一个
自定义负载数据的例子。该示例包含了可读性的空白符和换行符。为了提升性能,提
供者应该忽略空白符和换行符。
示例 1:如下负载包含哦一个简单的 aps 字典,采用默认的警告按钮的提示信息(关
闭按钮和查看按钮)。它使用字符串而不是字典做为 alert 的值。该负载一样包含了一
个自定义的属性数组。
{
“aps” : { “alert” : “Message received from Bob” },
“acme2″ : [ “bang”, “whiz” ]
}
示例 2:该示例的负载包含了一个 aps 的字典,指定设备显示一个警告消息并在左
边包含一个关闭按钮和右边显示一个本地化的”action”按钮。在该例中,”PLAY”被做
为键使用来从Localizable.strings文件里面当前偏好语言的字典里面获取对应的“Play”
的字符串。aps 字典一样要求应用程序的图标显示数字 5。
{
“aps” : {
“alert” : {
“body” : “Bob wants to play poker”,
“action-loc-key” : “PLAY”
},
“badge” : 5,
},
“acme1″ : “bar”,
“acme2″ : [ “bang”, “whiz” ]
}
2012-01-28 |© 2012 YouMi Mobile Co. Ltd. All Rights Reserved.                   
Local and Push Notification Programming Guide
示例 3:该示例的负载指定设备应用显示一个警告信息并包含关闭按钮和查看按
钮。同时它要求应用程序的图标显示数字 9,并在通知显示的时候播放主目录厦门的
bingbong.aiff 音频文件。
{
“aps” : {
“alert” : “You got your emails.”,
“badge” : 9,
“sound” : “bingbong.aiff”
},
“acme1″ : “bar”,
“acme2″ : 42
}
示例 4:该示例的负载主要关注的是使用 alert 字典里面的 loc-key 和 loc-args 子属
性来从应用程序的主目录下面获取一个本地化的字符串并根据 loc-args 选择合适的子
变量位于正确的位置。它一样指定了一个自定义声音文件 chime,并包含了一个自定
义属性。
{
“aps” : {
“alert” : { “loc-key” : “GAME_PLAY_REQUEST_FORMAT”, “loc-args” : [ “Jenna”,
“Frank”] },
“sound” : “chime”,
},
“acme” : “foo”
}
示例 5:下面的示例显示了一个空的 aps 字典,由于 badge 属性被隐藏了,因此当
前应用程序图标的任何数字都会被移除。而自定义属性 acme2 是一个包含两个整形的
数组。
{
“aps” : {
},
“acme2″ : [ 5, 8 ]
}

记住,为了更好的性能,你应该在把字符串添加到通知里面以前尽量的去除空
白字符和换行字符

 

8.2 检验证书是否正确的方法:

$ telnet gateway.sandbox.push.apple.com 2195

Trying 17.172.232.226…

Connected to gateway.sandbox.push-apple.com.akadns.net.

Escape character is ‘^]’.

它将尝试发送一个规则的,不加密的链接到APNS服务。若是你看到上面的反馈,那说明你的MAC可以到达APNS。按下Ctrl+C 关闭链接。若是获得一个错误信息,那么你须要确保你的防火墙容许2195端口。

而后再次链接,此次用咱们的SSL证书和私钥来设置一个安全的链接:

$ openssl s_client -connect gateway.sandbox.push.apple.com:2195

-cert PushChatCert.pem -key PushChatKey.pem

Enter pass phrase for PushChatKey.pem:

你会看到一个完整的输出,让你明白OpenSSL在后台作什么。若是链接是成功的,你能够键入一些字符。当你按下回车后,服务就会断开链接。若是在创建链接时有问题,OpenSSL将会给你一个错误消息,可是你不得不向上翻输出LOG,来找到它。

固然上面要测试prodution版本是否正确的话,把gateway.sandbox.push.apple.com换成gateway.push.apple.com就好。

 

8.3 Push故障排除

 

8.4 APNS信息包结构体

上图显示的这个消息体就是咱们的服务器(Provider)发送给APNS服务器的消息结构,APNS验证这个结构正确并提取其中的信息后,再将消 息推送到指定的设备。这个结构体包括五个部分,第一个部分是命令标示符,第二个部分是咱们的device_token的长度,第三部分是咱们的 device_token字符串,第四部分是推送消息体(Payload)的长度,最后一部分也就是真正的消息内容了,里面包含了推送消息的基本信息,比 如消息内容,应用Icon右上角显示多少数字以及推送消息到达时所播放的声音等。接下来咱们拆解看一下Payload(消息体)的结构:

{
“aps” : {
“alert” : “You got your emails.”,
“badge” : 1,
“sound” : “default”
},
}

这其实就是个JSON结构体,alert标签的内容就是会显示在用户手机上的推送信息,badge显示的数量(注意是整型)是会在应用Icon右上 角显示的数量,提示有多少条未读消息等,sound就是当推送信息送达是手机播放的声音,传defalut就标明使用系统默认声音,若是传好比 “beep.wav”就会播放在咱们应用工程目录下名称为beep.wav的音频文件,好比当手机锁屏时QQ在后台收到新消息时的滴滴声。

 

有这么一种状况,当咱们将应用从设备卸载后,推送的消息改如何处理呢。咱们知道,当咱们将应用从设备卸载后,咱们是收不到Provider给咱们推 送的消息的,可是,如何让APNS和Provider都知道不去向这台卸载了应用的设备推送消息呢?针对这个问题,苹果也已经帮咱们解决了,那就是 Feedback service。他是APNS的一部分,APNS会持续的更新Feedback service的列表,当咱们的Provider将信息发给APNS推送到咱们的设备时,若是这时设备没法将消息推送到指定的应用,就会向APNS服务器 报告一个反馈信息,而这个信息就记录在feedback service中。按照这种方式,Provider应该定时的去检测Feedback service的列表,而后删除在本身数据库中记录的存在于反馈列表中的device_token,从而再也不向这些设备发送推送信息。链接 Feedback service的过程一样使用Socket的方式,链接上后,直接接收由APNS传输给咱们的反馈列表,传输完成后断开链接,而后咱们根据这个最新的反馈 列表在更新咱们本身的数据库,删除那些再也不须要推送信息的设备的device_token。从Feedback service读取的数据结构以下:

结构中包含三个部分,第一部分是一个时间戳,记录的是设备失效后的时间信息,第二个部分是device_token的长度,第三部分就是失效的 device_token,咱们所要获取的就是第三部分,跟咱们的数据库进行对比后,删除对应的device_token,下次再也不向这些设备发送推送信 息

8.5 消息大批量发送问题

a.消息大批量发送问题

目前因为APNS(Apple Push Notification Service)机制缘由,目前easy apns的消息发送机制为:

对每一条发送的消息,为全部须要推送的设备都在数据库中apns_messages建立一条消息,而后经过轮训数据库表来一条一条向苹果消息推送服务器发送消息

在须要推送的设备较多的状况下,因为存在大量的网络连接,致使存在较长时间的延迟。

解决方案:

一、作批量消息推送时候,保持与苹果消息推送服务器的长连接

二、使用批量发送机制

You should also retain connections with APNs across multiple notifications. APNs may consider connections that are rapidly and repeatedly established and torn down as a denial-of-service attack. Upon error, APNs closes the connection on which the error occurred.

As a provider, you are responsible for the following aspects of push notifications:

You must compose the notification payload (see “The Notification Payload”).

You are responsible for supplying the badge number to be displayed on the application icon.

You should regularly connect with the feedback web server and fetch the current list of those devices that have repeatedly reported failed-delivery attempts. Then you should cease sending notifications to the devices associated with those applications. See “The Feedback Service” for more information.

b、数据库轮询效率问题

因为目前easy apns是采用数据库轮询的方式来进行消息推送,效率并不高,后期能够修改成Redis这样的NOSQL

 

8.6 参考链接

http://blog.sina.com.cn/s/blog_6f9a9718010128hi.html

http://blog.csdn.net/ryantang03/article/details/8482259

http://www.cnblogs.com/gpwzw/archive/2012/03/31/Apple_Push_Notification_Services_Tutorial_Part_1-2.html

http://www.devdiv.com/iOS_iPhone-_ios_push_-thread-130543-1-1.html

http://blog.sina.com.cn/s/blog_7cac85620100vv2b.html

http://www.cocoachina.com/bbs/read.php?tid=98797

相关文章
相关标签/搜索