我发送从php到ios的推送通知。它工作正常,这是我的代码:
$passphrase = '';
$badge = 1;
$path = base_path('path/to/certificate.pem');
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $path);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx
);
if (!$fp) {
self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "pending", "normal", null);
}
//echo 'Connected to APNS' . PHP_EOL;
$body['aps'] = array(
'alert' => $message,
'badge' => $badge,
'sound' => 'default'
);
$payload = json_encode($body);
$msg = chr(0) . pack('n', 32) . pack('H*', $device_token) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg));
//print_r($result);exit;
if (!$result) {
self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "pending", "normal", null, $result);
} else {
self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "sent", "normal", null, $result);
}
fclose($fp);
现在我面临的问题是,我无法确定通知是否失败,因为$result
在每种情况下都包含一个整数,成功或失败。我已经传递了一个随机数字作为标记,它返回115或65之类的整数,每次都会改变。所以!$result
不会工作。我怎么知道通知是否失败?
答案 0 :(得分:6)
对fwrite()的调用将返回它成功发送的字节数,如果发送错误则返回FALSE。您的$结果正在更改,因为它会随您发送的邮件大小而变化。所以知道这一点,你可以推测,如果$ result === FALSE,那么就会出现错误并且通知失败。如果$ result!== FALSE,则通知已成功发送。这仅验证消息是否通过网络发送。它不验证消息的结构或令牌的有效性或类似的东西。
现在,如果您试图找出推送通知消息本身是否有效并且苹果接受并正在处理它,那么您可能希望使用CURL和HTTP / 2来执行此操作。快速谷歌搜索我遇到了这个网站,它显示了如何做到这一点的演示。我没有测试过这个网站http://coding.tabasoft.it/ios/sending-push-notification-with-http2-and-php/,所以无法告诉你演示是否正确。这只是一个快速搜索,但可能会让你走上正确的轨道。
答案 1 :(得分:4)
使用fwrite
向APNS发送内容后,您需要fread
(或stream_get_contents
;))回复。最好的方法是使用非阻塞连接(stream_set_blocking($fp, 0);
)并在简单的限时循环中等待响应:
$read = '';
$to = time() + 2; // max 2 seconds wait...
while (!feof($fp)) // ...or end of connection
{
$r = stream_get_contents($fp);
if (strlen($r) > 0)
$read .= $r;
if (time() >= $to)
break;
usleep(100000);
}
之后,在$read
中,你会有什么东西或什么都没有。某些东西(确切地说是6个字节)意味着错误($error = unpack('Ccommand/Cstatus/Nident', $read);
)。没有(或内容短/长于6个字节)表示已成功发送消息。
答案 2 :(得分:4)
我的两分钱要清楚一点:正如苹果公司所说的那样,“推送无法保证”,因为推送工作正是这样。
所以你当然可以测试网络错误,正如其他人建议但你没有得到保证通知。为了获得这一点,唯一的(长...)方式是在接收推送时在iOS设备中触发URL请求。此URL请求将更新您的数据库。