APNS PHP不发送通知

时间:2016-12-23 14:34:58

标签: php ios apple-push-notifications

我已经使用PHP设置了APNS Provider Server。我连接到Apple的APNS服务器没有错误,脚本似乎运行正常,循环所有设备并发送有效负载。但是,订阅通知的设备上未收到通知。有人可以帮我找到我的代码中的错误吗?

$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 />&nbsp;&nbsp;&nbsp;&nbsp;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);

截图: enter image description here

2 个答案:

答案 0 :(得分:2)

执行以下步骤:
 1.检查pem文件是否有效。
 2.检查服务器上是否已打开端口2195。

3.如果你的pem文件是开发模式,使用“ssl://gateway.sandbox.push.apple.com:2195”连接到apns,否则如果你的pem文件是生产模式,则使用“ssl: //gateway.push.apple.com:2195“。

  1. 检查passpharas是否正确。
  2. 检查此示例代码:

    <?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);
    

答案 1 :(得分:1)

在进一步阅读文档后,我相信我已经找到了问题所在。我有一个数据库表,为应用程序的开发和生产版本保存设备令牌。显然,在尝试发送生产通知时,它在发送开发设备令牌后关闭了连接。我不确定为什么fwrite命令在连接关闭后没有发送错误,但是因为我从数据库表中删除了开发设备令牌,所以它现在似乎正在运行。