gpt4 book ai didi

php - APNS SSL 操作失败,代码为 1

转载 作者:可可西里 更新时间:2023-10-31 22:47:56 25 4
gpt4 key购买 nike

编辑 - 使用增强的二进制格式

原来我没有使用增强的二进制格式,所以我更改了我的代码。

<?php

$message = $_POST['message'];
$passphrase = $_POST['pass'];

//Connect to db


if ($db_found) {

// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);

$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', 'x.pem');
stream_context_set_option($streamContext, 'ssl', 'passphrase', $passphrase);

$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $error, $errorString, 15, STREAM_CLIENT_CONNECT, $streamContext);
stream_set_blocking ($fp, 0);

if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS for Push Notification' . PHP_EOL;

// Keep push alive (waiting for delivery) for 90 days
$apple_expiry = time() + (90 * 24 * 60 * 60);



$tokenResult = //SQL QUERY TO GET TOKENS

while($row = mysql_fetch_array($tokenResult)) {
$apple_identifier = $row["id"];
$deviceToken = $row['device_id'];
$payload = json_encode($body);

// Enhanced Notification
$msg = pack("C", 1) . pack("N", $apple_identifier) . pack("N", $apple_expiry) . pack("n", 32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n", strlen($payload)) . $payload;

// SEND PUSH
fwrite($fp, $msg);

// We can check if an error has been returned while we are sending, but we also need to
// check once more after we are done sending in case there was a delay with error response.
checkAppleErrorResponse($fp);
}

// Workaround to check if there were any errors during the last seconds of sending.
// Pause for half a second.
// Note I tested this with up to a 5 minute pause, and the error message was still available to be retrieved
usleep(500000);

checkAppleErrorResponse($fp);

echo 'Completed';

fclose($fp);


// SIMPLE BINARY FORMAT
/*for($i = 0; $i<count($deviceToken); $i++) {

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken[$i]) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

$bodyError .= 'result: '.$result.', devicetoken: '.$deviceToken[$i].'';

if (!$result) {
$errCounter = $errCounter + 1;
echo 'Message not delivered' . PHP_EOL;
}
else
echo 'Message successfully delivered' . PHP_EOL;
}*/


// Close the connection to the server
//fclose($fp);


//Insert message into database

mysql_close($db_handle);

}

else {

print "Database niet gevonden ";
mysql_close($db_handle);
}

// FUNCTION to check if there is an error response from Apple
// Returns TRUE if there was and FALSE if there was not
function checkAppleErrorResponse($fp) {

//byte1=always 8, byte2=StatusCode, bytes3,4,5,6=identifier(rowID).
// Should return nothing if OK.

//NOTE: Make sure you set stream_set_blocking($fp, 0) or else fread will pause your script and wait
// forever when there is no response to be sent.

$apple_error_response = fread($fp, 6);

if ($apple_error_response) {

// unpack the error response (first byte 'command" should always be 8)
$error_response = unpack('Ccommand/Cstatus_code/Nidentifier', $apple_error_response);

if ($error_response['status_code'] == '0') {
$error_response['status_code'] = '0-No errors encountered';

} else if ($error_response['status_code'] == '1') {
$error_response['status_code'] = '1-Processing error';

} else if ($error_response['status_code'] == '2') {
$error_response['status_code'] = '2-Missing device token';

} else if ($error_response['status_code'] == '3') {
$error_response['status_code'] = '3-Missing topic';

} else if ($error_response['status_code'] == '4') {
$error_response['status_code'] = '4-Missing payload';

} else if ($error_response['status_code'] == '5') {
$error_response['status_code'] = '5-Invalid token size';

} else if ($error_response['status_code'] == '6') {
$error_response['status_code'] = '6-Invalid topic size';

} else if ($error_response['status_code'] == '7') {
$error_response['status_code'] = '7-Invalid payload size';

} else if ($error_response['status_code'] == '8') {
$error_response['status_code'] = '8-Invalid token';

} else if ($error_response['status_code'] == '255') {
$error_response['status_code'] = '255-None (unknown)';

} else {
$error_response['status_code'] = $error_response['status_code'].'-Not listed';

}

echo '<br><b>+ + + + + + ERROR</b> Response Command:<b>' . $error_response['command'] . '</b>&nbsp;&nbsp;&nbsp;Identifier:<b>' . $error_response['identifier'] . '</b>&nbsp;&nbsp;&nbsp;Status:<b>' . $error_response['status_code'] . '</b><br>';

echo 'Identifier is the rowID (index) in the database that caused the problem, and Apple will disconnect you from server. To continue sending Push Notifications, just start at the next rowID after this Identifier.<br>';

return true;
}

return false;
}

?>

在使用这个新代码时,由于这个错误,我仍然无法发送超过 300 条消息:

Warning: fwrite() [function.fwrite]: SSL operation failed with code 1. OpenSSL Error messages: error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry in PATH_TO_SCRIPT.php on line NUMBER

此代码在发送少量推送消息时工作正常。

简单二进制格式的老问题所以我很久以前就集成了 Push Notifications,它可以很好地发送给不到 500 人的消息。现在我正尝试向 1000 多人发送推送通知,但随后我收到了损坏的错误

Warning: fwrite() [function.fwrite]: SSL: Broken pipe in PATH_TO.PHP on line x

我已经阅读了 apple 文档,我知道无效的 token 会导致套接字断开连接。一些在线解决方案建议像这样检测断开连接并重新连接:

Your server needs to detect disconnections and reconnect if necessary. Nothing is
"instant" when networking is involved; there's always some latency and code needs to take
that into account. Also, consider using the enhanced binary interface so you can check the
return response and know why the connection was dropped. The connection can also be
dropped as a result of TCP keep-alive, which is outside of Apple's control.

我还运行了一个反馈服务,它检测无效的 token (想要推送通知但删除了应用程序的用户)并且工作正常。该 php 脚本回显了已删除的 ID,我可以确认这些标记已从我们的 MySQL 数据库中删除。

我如何能够检测到断开连接或破损的管道并对此使用react,以便我的推送通知可以到达 1000 多人?

目前我正在使用这个简单的 push.php 脚本。

<?php

$message = $_POST['message'];
$passphrase = $_POST['pass'];

//Connect to database stuff

if ($db_found) {
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', 'x.pem');
stream_context_set_option($streamContext, 'ssl', 'passphrase', $passphrase);

$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $error, $errorString, 15, STREAM_CLIENT_CONNECT, $streamContext);

if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS for Push Notification' . PHP_EOL;

$deviceToken[] = //GET ALL TOKENS FROM DATABASE AND STORE IN ARRAY

for($i = 0; $i<count($deviceToken); $i++) {
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken[$i]) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

$bodyError .= 'result: '.$result.', devicetoken: '.$deviceToken[$i].'';

if (!$result) {
$errCounter = $errCounter + 1;
echo 'Message not delivered' . PHP_EOL;
}
else
echo 'Message successfully delivered' . PHP_EOL;
}


echo $bodyError;

// Close the connection to the server
fclose($fp);


//CODE TO SAVE MESSAGE TO DATABSE HERE

if (!mysql_query($SQL,$db_handle)) {
die('Error: ' . mysql_error());
}

}
else {
print "Database niet gevonden ";
mysql_close($db_handle);
}


?>

当发生 SLL Broken Pipe 错误时,fwrite 也返回 0 个写入字节。

我还必须提到,我不是 PHP 或 Web 开发人员,而是应用程序开发人员,所以我的 PHP 技能不是那么好。

最佳答案

当你这样做时:

fwrite($fp, $msg);

您正在尝试写入套接字。如果出现问题,fwrite 将返回 false 或 0(取决于 php 版本)作为返回值。当它发生时,你必须管理它。您有两种可能性:

  • 放弃整个操作
  • 重试上次的写操作

如果您选择第二个选项,则必须使用失败的 fwrite() fwrite($fp, $msg)操作。如果更改参数,将返回 1409F07F:SSL 错误

此外,有些情况下 fwrite 仅写入“一些字节”失败,您甚至应该管理这种情况,将返回值与 $msg 的长度进行比较。在这种情况下,您应该发送消息的剩余部分,但在某些情况下您必须再次发送整个消息(根据 this link )。

查看 fwrite 引用和注释:Link

关于php - APNS SSL 操作失败,代码为 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18378534/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com