APNS PHP不发送通知
我已经使用PHP设置和APNS提供程序服务器。我连接到苹果的APNS服务器时没有出现任何错误,脚本似乎运行良好,在所有设备中循环并发送有效负载。但是,在已订阅通知的设备上未接收到通知。有人能帮我找到代码中的错误吗APNS PHP不发送通知,php,ios,apple-push-notifications,Php,Ios,Apple Push Notifications,我已经使用PHP设置和APNS提供程序服务器。我连接到苹果的APNS服务器时没有出现任何错误,脚本似乎运行良好,在所有设备中循环并发送有效负载。但是,在已订阅通知的设备上未接收到通知。有人能帮我找到代码中的错误吗 $message = $_POST['message']; echo "Posted Message: $message<br />"; $message = str_replace("'", "\'", $message); echo "Formatted messag
$message = $_POST['message'];
echo "Posted Message: $message<br />";
$message = str_replace("'", "\'", $message);
echo "Formatted message: $message<br />";
$title = $_POST['title'];
$title = str_replace("'", "\'", $title);
echo "Formatted Title: $title<br />";
$category = $_POST['category'];
echo "Category: $category<br />";
$alert = array('title' => "$title", 'body' => "$message");
foreach ($alert as $key => $value){
echo "Key: $key Value: $value<br />";
}
ini_set("display_errors",1);
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apns.pem';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if ($error!="" || $errorString!=""){
echo "Error Connecting: $error : $errorString<br />";
}
else{
echo "No Error Connecting<br />";
}
$query = "INSERT INTO notifications (`title`, `message`, `category`) VALUES (\"$title\", \"$message\", \"$category\")";
echo "Insert Query: $query<br />";
$result1 = mysqli_query($connection, $query);
$query = "SELECT * FROM notifications ORDER BY notification_id DESC";
$result931 = mysqli_query($connection, $query);
$row = $result931->fetch_assoc();
$notification_id = $row[notification_id];
$query = "SELECT * FROM category_subscriptions WHERE category_id='$category' ORDER BY device_id";
$result1 = mysqli_query($connection, $query);
echo "Subscriber Query: $query<br />";
while($row = $result1->fetch_assoc()) {
$device_id = $row[device_id];
$query = "SELECT * FROM devices WHERE device_id='$device_id' ORDER BY device_id";
$result = mysqli_query($connection,$query);
while($r = $result->fetch_assoc()) {
$deviceToken = $r[device_token];
$badge = $r[badge_value] + 1;
if ($r[accepts_alerts]==1) {
if ($r[accepts_badges]==1) {
if ($r[accepts_sounds]==1) {
$payload['aps'] = array('alert' => $alert, 'badge' => $badge, 'sound' => 'default');
} else {
$payload['aps'] = array('alert' => $alert, 'badge' => $badge);
}
}
else if ($r[accepts_sounds]==1) {
$payload['aps'] = array('alert' => $alert, 'sound' => 'default');
}
else {
$payload['aps'] = array('alert' => $alert);
}
$payload1 = json_encode($payload);
echo "Payload: $payload1<br />";
echo "<br /> Sending to Device Token: $deviceToken<br />";
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload1)) . $payload1;
echo "APNS Message: $apnsMessage<br />";
fwrite($apns, $apnsMessage);
$query6 = "UPDATE devices SET badge_value = $badge WHERE device_id='$device_id'";
$result6 = mysqli_query($connection,$query6);
$query7 = "INSERT INTO notification_map (`device_id`, `notification_id`, `viewed`) VALUES ($device_id, $notification_id, \"false\")";
$result7 = mysqli_query($connection,$query7);
}
}
}
fclose($apns);
$message=$\u POST['message'];
回显“已发布消息:$Message
”;
$message=str\u replace(“'”、“\'”、$message);
echo“格式化消息:$message
”;
$title=$_POST['title'];
$title=stru替换(“'”、“\'”、$title);
echo“格式化标题:$Title
”;
$category=$_POST['category'];
echo“类别:$Category
”;
$alert=array('title'=>“$title”、'body'=>“$message”);
foreach($key=>$value的警报){
echo“Key:$Key-Value:$Value
”;
}
ini设置(“显示错误”,1);
$apnsHost='gateway.push.apple.com';
$apnsPort=2195;
$apnsCert='apns.pem';
$streamContext=stream_context_create();
stream_context_set_选项($streamContext,'ssl','local_cert',$apnsCert);
$apns=stream_socket_client('ssl://'.$apnsHost'.:'.$apnsPort,$error,$errorString,2,stream_client_CONNECT,$streamContext);
如果($error!=“”| |$errorString!=“”){
echo“连接错误:$Error:$errorString
”;
}
否则{
echo“连接
时无错误”;
}
$query=“插入通知(`title`、`message`、`category`)值(\“$title\”、\“$message\”、\“$category\”);
echo“插入查询:$Query
”;
$result1=mysqli\u查询($connection,$query);
$query=“按通知从通知订单中选择*_iddesc”;
$result931=mysqli_查询($connection,$query);
$row=$result931->fetch_assoc();
$notification_id=$row[notification_id];
$query=“从类别订阅中选择*,其中类别id=“$category”按设备id排序”;
$result1=mysqli\u查询($connection,$query);
echo“订户查询:$Query
”;
而($row=$result1->fetch_assoc()){
$device_id=$row[device_id];
$query=“从设备中选择*,其中设备标识=“$device\u id”按设备标识排序”;
$result=mysqli\u查询($connection,$query);
而($r=$result->fetch_assoc()){
$deviceToken=$r[设备令牌];
$badge=$r[badge_值]+1;
如果($r[接受\u警报]==1){
如果($r[接受徽章]==1){
如果($r[接受声音]==1){
$payload['aps']=array('alert'=>$alert,'badge'=>$badge,'sound'=>'default');
}否则{
$payload['aps']=阵列('alert'=>$alert,'badge'=>$badge);
}
}
else if($r[接受声音]==1){
$payload['aps']=array('alert'=>$alert,'sound'=>'default');
}
否则{
$payload['aps']=array('alert'=>$alert);
}
$payload1=json_encode($payload1);
echo“有效载荷:$payload1
”;
echo“
发送到设备令牌:$deviceToken
”;
$apnsMessage=chr(0).chr(0).chr(32).pack('H*',str_replace('',$deviceToken)).chr(0).chr(strlen($payload1))。$payload1;
回显“APNS消息:$apnsMessage
”;
fwrite($apns,$apnsMessage);
$query6=“更新设备设置标记\u值=$badge,其中设备\u id='$device\u id'”;
$result6=mysqli_查询($connection,$query6);
$query7=“插入通知映射(`device\u id`、`notification\u id`、`viewsed`)值($device\u id、`notification\u id、\'false\”);
$result7=mysqli_查询($connection,$query7);
}
}
}
fclose($apns);
截图:
执行以下步骤:
1.检查pem文件是否有效。
2.检查服务器上的端口2195是否打开 3.如果您的pem文件属于开发模式,请使用“ssl://gateway.sandbox.push.apple.com:2195“如果您的pem文件处于生产模式,则连接到APN,否则将无法使用”ssl://gateway.push.apple.com:2195" .
<?php
// Put your device token here (without spaces):
$deviceToken = 'fefb03ba6adcea310cf3f455dae16fec4f63b4ba4d96103c20d594a04efd7c2a';
// Put your private key's passphrase here:
$passphrase = 'Welcome@1';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'title' => 'testing title'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
进一步阅读文档后,我相信我已经解决了我的问题。我有一个数据库表,其中包含应用程序开发和生产版本的设备令牌。显然,当尝试发送生产通知时,它在发送开发设备令牌后关闭了连接。我不确定为什么fwrite命令在连接关闭后没有发送错误,但由于我从数据库表中删除了开发设备令牌,它现在似乎正在工作。您确定正在使用生产证书吗?您是否尝试过使用APNS测试应用程序来确保?我使用的证书是生产证书,但是,老实说,我不确定我是否完全理解证书创建过程。在开发模式下,我的应用程序向循环中的第一个设备发送通知,但随后无法与后续设备一起发送。我假设它在这里做同样的事情,但无法确定,因为我的设备不是循环中的第一个设备。刚刚验证,它正在向循环中的第一个设备发送通知,但在所有后续设备上都失败。如果PEM文件无效或端口未打开,我在连接时不应该出错吗?有没有办法测试PEM文件,看看它是否有效?如果我没记错的话,我没有为我的证书设置密码短语,我正在使用的密码短语应该是生产证书,尽管正如我在回复ValyreanGroup时提到的,我不确定我是否有足够多的证书句柄……我只是返回并查看了stream_socket_客户端调用的参数。我注意到我已经把它设置为2秒后超时。也许这就是问题所在。我会调整它,看看它是否能解决我的问题。嗨,Richard,你救了我的命~我和你一样有同样的问题,而且困了3-4天。在我移除所有dev toke之后