Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Apple推送通知的curl请求太多_Php_Curl_Apple Push Notifications - Fatal编程技术网

Php Apple推送通知的curl请求太多

Php Apple推送通知的curl请求太多,php,curl,apple-push-notifications,Php,Curl,Apple Push Notifications,我正在使用此功能发送推送通知 function SendPush($token,$message,$badge,$eventid) { $device_token = $token; $pem_file = '../pushcert.pem'; $pem_secret = 'pass'; $apns_topic = 'com.topic'; $sample_alert = '{"aps":{"alert":"'. $m

我正在使用此功能发送推送通知

function SendPush($token,$message,$badge,$eventid) {

    $device_token   = $token;
    $pem_file       = '../pushcert.pem';
    $pem_secret     = 'pass';
    $apns_topic     = 'com.topic';


    $sample_alert = '{"aps":{"alert":"'. $message .'","sound":"default","badge":'. $badge .'}, "type":"attend", "eventID":"'.$eventid.'"}';
    $url = "https://api.push.apple.com/3/device/$device_token";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $sample_alert);
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, true );
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("apns-topic: $apns_topic"));
    curl_setopt($ch, CURLOPT_SSLCERT, $pem_file);
    curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $pem_secret);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    $response = curl_exec($ch);
    $sonuc = json_decode($response,true);

    if ($sonuc['reason'] == "BadDeviceToken" || $sonuc['reason'] == "Unregistered" ) {
        return false;
    } else {
        return true;
    }

}
它工作得很好。我还可以检测无效令牌

我的问题是,当我需要发送超过1000个推送通知时,这会花费太多时间

有没有一种方法可以让curl连接保持活动状态并更快地发送通知,而不会被苹果服务器阻止?

有curl multi

<?php
//$message should be an array with the details
function SendPush($messages) {
$mh = curl_multi_init();
$ch = array();
foreach($messages as $key=>$mess)
{
    $device_token   = $mess['token'];
    $pem_file       = '../pushcert.pem';
    $pem_secret     = 'pass';
    $apns_topic     = 'com.topic';
    $sample_alert = '{"aps":{"alert":"'. $mess['message'] .'","sound":"default","badge":'. $mess['badge'] .'}, "type":"attend", "eventID":"'.$mess['eventid'].'"}';
    $url = "https://api.push.apple.com/3/device/$device_token";
    $ch[$key]=curl_init($url);
    curl_setopt($ch[$key], CURLOPT_POSTFIELDS, $sample_alert);
    curl_setopt($ch[$key], CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
    curl_setopt($ch[$key],CURLOPT_RETURNTRANSFER, true );
    curl_setopt($ch[$key], CURLOPT_HTTPHEADER, array("apns-topic: $apns_topic"));
    curl_setopt($ch[$key], CURLOPT_SSLCERT, $pem_file);
    curl_setopt($ch[$key], CURLOPT_SSLCERTPASSWD, $pem_secret);
    curl_setopt($ch[$key], CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch[$key], CURLOPT_TIMEOUT, 15);
    curl_multi_add_handle($mh,$ch[$key]);

}
$running = null;
do {
  curl_multi_exec($mh, $running);
} while ($running);

$sonuc = json_decode($response,true);
foreach($ch as $curl)
{
    $response = curl_multi_getcontent($curl);
    if ($sonuc['reason'] == "BadDeviceToken" || $sonuc['reason'] == "Unregistered" ) {
        //return false;
        //handle the bad device
    } else {
        //return true;
        //device ok
    }
}
}

为此,您必须将通知代码放在后台

您可以参考此URL:

因此,您的代码将在1秒内执行,并且您的通知将从后台发送,因此,您不必等待响应,直到通知完成

您可以使用第三方通知工具

FCM:

OneSignal:


PHP curl库默认情况下应该重用HTTP连接,您只需要重用curl句柄。 所以,解决方案是执行$ch=curl\u init($url)一次,在此方法之外,然后在处理/发送通知的循环中向SendPush()添加$ch作为参数


这样,您的HTTP连接将是持久的,并将节省大量的连接建立时间。在不增加成本和复杂性的情况下,您可以获得排队效果。

您可以使用“连接池”。Guzzle(无论何时你需要做cURL-y之类的事情,它都非常棒)有一个内置的系统:(请参阅“当你有不确定数量的请求时,你可以使用GuzzleHttp\Pool对象。”)警告,
$mess['message']
$mess['badge']
,以及
$mess['eventid']
此处未正确进行json编码。请将传递给原始函数的项作为数组传递给此函数。每个推送通知对应一个数组项。我认为这应该是显而易见的。在后台执行curl后,如何得到它的结果*ignore\u user\u abort(true);美国LEEP(500000);//等待500毫秒//do Stuff不能这样做,因为URL在每个函数调用中都在更改,所以我需要重新设置URL,只要URL的主机部分没有更改-是的,您可以。