apns-http2-php,苹果push升级到http2

最近公司push推送升级,用苹果http2进行推送,http2的好处就不说了,这些网上都可以查到,但是真正在项目中用的,用php写的还是特别少,因此,写出来跟大家分享,废话不说了,直接上代码:

pushMessage.php

<?php

class PushMessage {
//发送apns server时发送消息的键
const APPLE_RESERVED_NAMESPACE = ‘aps‘;

/*
* 连接apns地址
* ‘https://api.push.apple.com:443/3/device/‘, // 生产环境
* ‘https://api.development.push.apple.com:443/3/device/‘ // 沙盒环境
*
**/
private $_appleServiceUrl;
//证书
private $_sProviderCertificateFile;
//要发送到的device token
private $_deviceTokens = array();
//额外要发送的内容
private $_customProperties;
//私钥密码
private $_passPhrase;
//要推送的文字消息
private $_pushMessage;
//要推送的语音消息
private $_pushSoundMessage;
//设置角标
private $_nBadge;
//发送的头部信息
private $_headers = array();
private $_errors;
//推送的超时时间,如果超过了这个时间,就自动不推送了,单位为秒
private $_expiration;
//apple 唯一标识
private $_apns_topic;
//10:立即接收,5:屏幕关闭,在省电时才会接收到的。如果是屏幕亮着,是不会接收到消息的。而且这种消息是没有声音提示的
private $_priority;
//cURL允许执行的最长秒数
private $_timeout;
/**< @type integer Status code for internal error (not Apple). */
const STATUS_CODE_INTERNAL_ERROR = 999;

const ERROR_WRITE_TOKEN = 1000;
//apple server 返回的错误信息
protected $_aErrorResponseMessages = array(
200 => ‘Sussess‘,
400 => ‘Bad request‘,
403 => ‘There was an error with the certificate‘,
405 => ‘The request used a bad :method value. Only POST requests are supported‘,
410 => ‘The device token is no longer active for the topic‘,
413 => ‘The notification payload was too large‘,
429 => ‘The server received too many requests for the same device token‘,
500 => ‘Internal server error‘,
503 => ‘The server is shutting down and unavailable‘,
self::STATUS_CODE_INTERNAL_ERROR => ‘Internal error‘,
self::ERROR_WRITE_TOKEN => ‘Writing token error‘,
);

public function __construct() {}

/*
* 连接apple server
* @params certificate_file 证书
* @params pass_phrase 私钥密码
* @params apple_service_url 要发送的apple apns service
* @params expiration 推送的超时时间,如果超过了这个时间,就自动不推送了,单位为秒
* @params apns-topic apple标识
**/
public function connServer($params) {
if (empty($params[‘certificate_file‘])) {
return false;
}
$this->_sProviderCertificateFile = $params[‘certificate_file‘];
$this->_appleServiceUrl = $params[‘apple_service_url‘];
$this->_passPhrase = $params[‘pass_phrase‘];
$this->_apns_topic = $params[‘apns-topic‘];
$this->_expiration = $params[‘expiration‘];
$this->_priority = $params[‘priority‘];
$this->_timeout = $params[‘timeout‘];

$this->_headers = array(
‘apns-topic:‘. $params[‘apns-topic‘],
‘apns-priority‘. $params[‘priority‘],
‘apns-expiration‘. $params[‘expiration‘]
);

$this->_hSocket = curl_init();
if(!defined(CURL_HTTP_VERSION_2_0)) {
define(CURL_HTTP_VERSION_2_0, 3);
}
curl_setopt($this->_hSocket, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
curl_setopt($this->_hSocket, CURLOPT_SSLCERT, $this->_sProviderCertificateFile);
curl_setopt($this->_hSocket, CURLOPT_SSLCERTPASSWD, $this->_passPhrase);
curl_setopt($this->_hSocket, CURLOPT_SSLKEYTYPE, ‘PEM‘);
curl_setopt($this->_hSocket, CURLOPT_TIMEOUT, $this->_timeout);

if (!$this->_hSocket) {
$this->_errors[‘connServer‘][‘cert‘] = $this->_sProviderCertificateFile;
$this->_errors[‘connServer‘][‘desc‘] = "Unable to connect to ‘{$this->_appleServiceUrl}‘: $this->_hSocket";
$this->_errors[‘connServer‘][‘nums‘] = isset($this->_errors[‘connServer‘][‘nums‘]) ? intval($this->_errors[‘connServer‘][‘nums‘]) : 0;
$this->_errors[‘connServer‘][‘nums‘] += 1;
return false;
}

return $this->_hSocket;
}

/*
* 断连
*
**/
public function disconnect() {
if (is_resource($this->_hSocket)) {
return curl_close($this->_hSocket);
}
return false;
}

//设置发送文字消息
public function setMessage($message) {
$this->_pushMessage = $message;
}
//设置发送语音消息
public function setSound($sound_message = ‘default‘) {
$this->_pushSoundMessage = $sound_message;
}

//获取要发送的文字消息
public function getMessage() {
if (!empty($this->_pushMessage)) {
return $this->_pushMessage;
}
return ‘‘;
}

//获取语音消息
public function getSoundMessage() {
if (!empty($this->_pushSoundMessage)) {
return $this->_pushSoundMessage;
}
return ‘‘;
}

/*
* 接收device token 可以是数组,也可以是单个字符串
*
**/
public function addDeviceToken($device_token) {
if (is_array($device_token) && !empty($device_token)) {
$this->_deviceTokens = $device_token;
} else {
$this->_deviceTokens[] = $device_token;
}
}

//返回要获取的device token
public function getDeviceToken($key = ‘‘) {
if ($key !== ‘‘) {
return isset($this->_deviceTokens[$key]) ? $this->_deviceTokens[$key] : array();
}
return $this->_deviceTokens;
}

//设置角标
public function setBadge($nBadge) {
$this->_nBadge = intval($nBadge);
}
//获取角标
public function getBadge() {
return $this->_nBadge;
}

/*
* 用来设置额外的消息
* @params custom_params array $name 不能和 self::APPLE_RESERVED_NAMESPACE(‘aps‘)样,
*
**/
public function setCustomProperty($custom_params) {
foreach($custom_params as $name=>$value){
if (trim($name) == self::APPLE_RESERVED_NAMESPACE) {
$this->_errors[‘setCustomProperty‘][] = $name.‘设置不成功,‘.$name.‘不可以设置成 aps.‘;
}
$this->_customProperties[trim($name)] = $value;
}
}

/*
* 用来获取额外设置的值
* @params string $name
*
**/
public function getCustomProperty($name = ‘‘) {
if($name !== ‘‘){
return isset($this->_customProperties[trim($name)]) ? $this->_customProperties[trim($name)] : ‘‘;
}

return $this->_customProperties;
}

/**
* 组织发送的消息
*
* @return @type array The payload dictionary.
*/
protected function getPayload() {
$aPayload[self::APPLE_RESERVED_NAMESPACE] = array();

if (isset($this->_pushMessage)) {
$aPayload[self::APPLE_RESERVED_NAMESPACE][‘alert‘] = $this->_pushMessage;
}
if (isset($this->_pushSoundMessage)) {
$aPayload[self::APPLE_RESERVED_NAMESPACE][‘sound‘] = (string)$this->_pushSoundMessage;
}
if (isset($this->_nBadge)) {
$aPayload[self::APPLE_RESERVED_NAMESPACE][‘badge‘] = (int)$this->_nBadge;
}

if (is_array($this->_customProperties) && !empty($this->_customProperties)) {
foreach($this->_customProperties as $sPropertyName => $mPropertyValue) {
$aPayload[$sPropertyName] = $mPropertyValue;
}
}

return json_encode($aPayload);
}

/*
* 推送消息
*
**/
public function send() {
if (!$this->_hSocket) {
return false;
}
if (isset($this->_errors[‘connServer‘])) {
unset($this->_errors[‘connServer‘]);
}

if (empty($this->_deviceTokens)) {
$this->_errors[‘send‘][‘not_deviceTokens‘][‘desc‘] = ‘No device tokens‘;
$this->_errors[‘send‘][‘not_deviceTokens‘][‘time‘] = date("Y-m-d H:i:s",time());
return false;
}

if (empty($this->getPayload())) {
$this->_errors[‘send‘][‘not_message‘][‘desc‘] = ‘No message to push‘;
$this->_errors[‘send‘][‘not_message‘][‘time‘] = date("Y-m-d H:i:s",time());
return false;
}

$tmpfile = tmpfile();
foreach ($this->_deviceTokens as $token) {
$sendMessage = $this->getPayload();
curl_setopt($this->_hSocket, CURLOPT_URL, $this->_appleServiceUrl . $token);
curl_setopt($this->_hSocket, CURLOPT_POSTFIELDS, $sendMessage);
curl_setopt($this->_hSocket, CURLOPT_HTTPHEADER, $this->_headers);
curl_setopt($this->_hSocket, CURLOPT_FILE, $tmpfile);

$response_info = curl_exec($this->_hSocket);
$response_code = curl_getinfo($this ->_hSocket,CURLINFO_HTTP_CODE);

if(!$response_info) {
$this->_errors[‘send‘][‘exec_curl‘][‘desc‘] = "curl connect faild";
$this->_errors[‘send‘][‘exec_curl‘][‘time‘] = date("Y-m-d H:i:s", time());
}

$response_errors = array();
fseek($tmpfile, 0);
while(($line = fgets($tmpfile)) !== false) {
$response_errors[] = json_decode($line, true);
}

if ($response_code != 200) {
$this->_writeErrorMessage($response_errors, $response_code, $token);
}
}

fclose($tmpfile);
$this->_deviceTokens = array();
return true;
}

//获取发送过程中的错误
public function getError() {
return $this->_errors;
}

/*
* 读取错误信息
*@params res_errors 发送失败的具体信息
*@params res_code 响应头返回的错误code
*@params token 发送失败的device token
**/
protected function _writeErrorMessage($res_errors, $res_code, $token) {
if(isset($this->_aErrorResponseMessages[$res_code])) {
$this->_errors[‘send‘][‘response‘][] = array(
‘reason‘ => $res_errors,
‘response_code‘ => $res_code,
‘msg‘ => $this->_aErrorResponseMessages[$res_code],
‘token‘ => $token,
‘time‘ => date("Y-m-d H:i:s",time())
);
} else {
$this->_errors[‘send‘][‘response‘][] = array(
‘reason‘ => $res_errors,
‘response_code‘ => $res_code,
‘token‘ => $token,
‘time‘ => date("Y-m-d H:i:s")
);
}

$this->disconnect();
sleep(0.5);
$this->_resConnect();
}

//重新连接
protected function _resConnect() {
$conn_res = $this->connServer(array(
‘certificate_file‘ => $this->_sProviderCertificateFile,
‘apple_service_url‘ => $this->_appleServiceUrl,
‘pass_phrase‘ => $this->_passPhrase,
‘priority‘ => $this->_priority,
‘apns-topic‘ => $this->_apns_topic,
‘expiration‘ => $this->_expiration,
‘timeout‘ => $this->_timeout
));

if (!$conn_res) {
$this->_errors[‘connServer‘][‘res_conn_nums‘] = isset($this->_errors[‘connServer‘][‘res_conn_nums‘]) ? intval($this->_errors[‘connServer‘][‘res_conn_nums‘]) : 0;
$this->_errors[‘connServer‘][‘res_conn_nums‘] += 1;
if ($this->_errors[‘connServer‘][‘res_conn_nums‘] >=5) {
return false;
}

return $this->_resConnect();
}
if (isset($this->_errors[‘connServer‘])) {
unset($this->_errors[‘connServer‘]);
}
return true;
}

}

使用:

include "pushMessage.php";

$obj = new PushMessage();

$params = array(

  ‘certificate_file‘ =>证书路径 ,// .pem 文件

  ‘apple_service_url‘ => // 生产环境: ‘https://api.push.apple.com:443/3/device/‘  沙盒环境 ‘https://api.development.push.apple.com:443/3/device/‘

  ‘pass_phrase‘ => //这个是证书的私钥密码
  ‘apns-topic‘  => //apple唯一标识,这个不是随便的字符串,应该是申请苹果推送的时候有的吧,具体不清楚,这个要问负责人

  ‘expiration‘ =>0,  //推送的超时时间,如果超过了这个时间,就自动不推送了,单位为秒, 一般默认为0

  ‘priority‘  => 10,//10:立即接收,5:屏幕关闭,在省电时才会接收到的。如果是屏幕亮着,是不会接收到消息的。而且这种消息是没有声音提示的,一般为10

  ‘timeout‘ => 30,//curl超时时间,单位为秒

);

//设置发送的文字还是声音或者角标什么的按自己的需求调用

$obj->connServer($params);

$obj->setMessage = "要发送的文字";

$obj->setSound = "要发送的声音";

$obj->addDeviceToken= array();//或者单个的device token, 要发送到的apple token

$obj->setBadge = 1;//设置角标

$obj->setCustomProperty = array(‘a‘=>‘b‘);//其他额外发送的参数

$obj->getPayload(); //组织发送

$obj->send();//发送

$obj->getError();//获取发送过程中的错误

$obj->disconnect();//断连

注意:转载请注明出处,谢谢!

时间: 2024-11-04 14:28:57

apns-http2-php,苹果push升级到http2的相关文章

nginx如何启用对HTTP2的支持 | nginx如何验证HTTP2是否已启用

本文标签:   Nginx HTTP2 nginx启用HTTP2支持 nginx验证HTTP2 启用http2支持   服务器 nginx启用HTTP2特性 查看当前nginx的编译选项 1 #./nginx -V 2   3 nginx version: nginx/1.9.15 4 built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5 built with OpenSSL 1.0.2g  1 Mar 2016 6 TLS

苹果5s升级ios8后无法正常使用siri

苹果5s于9月18日升级ios8,升级后效果很好,除去微博闪退,其他功能很正常. 更新完毕后使用wifi连接siri正常并且相应速度以及识别率很高,但是3G网络识别很慢,有卡顿现象,能提供服务 9月19日早上使用siri时候发现以下情况请看图片!

记升级一次的http2学习

首先,就先对比下http2和http1.X的区别和升级它的优势吧. 在 HTTP 1.X 中,为了性能考虑,我们会引入雪碧图.将小图内联.使用多个域名等等的方式.这一切都是因为浏览器限制了同一个域名下的请求数量,当页面中需要请求很多资源的时候,队头阻塞(Head of line blocking)会导致在达到最大请求数量时,剩余的资源需要等待其他资源请求完成后才能发起请求 http2.0引入了多路复用 在 HTTP 2.0 中,有两个非常重要的概念,分别是帧(frame)和流(stream).

HTTP2.0那些事

1. HTTP2.0的前世 http2.0的前世是http1.0和http1.1这两兄弟.虽然之前仅仅只有两个版本,但这两个版本所包含的协议规范之庞大,足以让任何一个有经验的工程师为之头疼.http1.0诞生于1996年,协议文档足足60页.之后第三年,http1.1也随之出生,协议文档膨胀到了176页.不过和我们手机端app升级不同的是,网络协议新版本并不会马上取代旧版本.实际上,1.0和1.1在之后很长的一段时间内一直并存,这是由于网络基础设施更新缓慢所决定的.今天的http2.0也是一样,

HTTP,HTTP2.0,SPDY,HTTPS你应该知道的一些事

转载自AlloyTeam:http://www.alloyteam.com/2016/07/httphttp2-0spdyhttps-reading-this-is-enough/ 1. web始祖HTTP 全称:超文本传输协议(HyperText Transfer Protocol) 伴随着计算机网络和浏览器的诞生,HTTP1.0也随之而来,处于计算机网络中的应用层,HTTP是建立在TCP协议之上,所以HTTP协议的瓶颈及其优化技巧都是基于TCP协议本身的特性,例如tcp建立连接的3次握手和断

HTTP、HTTP2

HTTP.HTTP2.0.SPDY.HTTPS 你应该知道的一些事 原文链接:http://www.alloyteam.com/2016/07/httphttp2-0spdyhttps-reading-this-is-enough/ 作为一个经常和 web 打交道的程序员,了解这些协议是必须的,本文就向大家介绍一下这些协议的区别和基本概念,文中可能不局限于前端知识,还包括一些运维,协议方面的知识 -- 由 MrDream24 分享 作为一个经常和web打交道的程序员,了解这些协议是必须的,本文就

苹果APNs’ device token特性和过期更新

APNs全名是Apple Push Notification Service.用iPhone的应该都习惯了,每次安装完一个新应用启动后,几乎都会弹出个警告框,“XXX应用”想要给您发送推送通知.这个警告框的权限申请就是为了APNs推送,用户授权后,应用提供商就可以通过APNs给用户推送消息.APNs的工作机制简单来说可以分为两步,第一步是注册推送服务从APNs获取device token来告知应用提供商服务端,第二步是应用提供商服务端通过APNs给设备推送消息,device token是作为设备

nginx配置支持http2

遇到问题:开发提出需求,某站点的访问需要支持http2 解决问题:配置nginx支持http2 http2 的支持需要nginx版本>1.9.5 .请参考升级nginx版本http://mengsir.blog.51cto.com/2992083/1859838 http2突出的优点: 多路复用与并发性 报头压缩 HTTP/2能够显著改进当前网络的性能与安全性/隐私性,对于带宽不高的网络用户尤其如此. 在startssl上申请好证书.能被你的浏览器认可. 去年申请免费的证书还是1年有效期,今天申

HTTP2 学习

一.HTTP1.x存在的问题 Http1.0时Connection无法复用,同一时间一个Connection只能处理一个request.Http1.1引入了Request pipelining来解决这一问题,Request pipelining. Requestpipeling在FIFO基础上支持同一Connection并发处理多个Request,这里的FIFO是指Http Response发送顺序必须与Request的发送顺序保持一致. 详情前往https://en.wikipedia.org