我正在使用 this tutorial 来学习推送通知。
<?php
// Put your device token here (without spaces):
$deviceToken = '1675ba8bb005740bb514222227f861c30230a81e6eed6bb6b8f353c57831341d';
// Put your private key's passphrase here:
$passphrase = '111134';
// 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'
);
// 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));
echo 'result =' . $result. PHP_EOL;
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
我还为推送通知配置应用。配置推送后,我还重新创建配置文件,旧删除一个,安装新的配置文件。 我运行app它给我设备ID然后我连接服务器沙箱和生产发送推送通知与他们的相对推送配置文件但仍然我无法在我的设备上接收推送通知。
我还在我的设备上安装ipusher并检查推送通知。他们来自那个应用程序。
我注意到一个奇怪的事情是我更改了我的应用程序标识符并使用任何其他应用程序ID,然后设备令牌保持不变
现在我的问题是我没有收到设备上的推送通知。
问题不在我的个人资料中。可能是错误是我正在使用的PHP代码,因为当我在远程服务器上使用简单的apns然后它发送推送通知。 收到的通知时间为6到7个小时。我认为这是由于设备端的网络问题。 但现在它在生产情况下2天后工作正常。现在通知很快就可以在我的设备上发送,但在某些设备上需要30秒到5分钟。
如果您没有从其他应用程序接收设备上的推送通知,还有一个问题,那么您应该检查DNS以获取连接。
答案 0 :(得分:7)
首先确保您正在使用:
然后使用以下代码(已经测试了开发和生产)
<?php
// Comment these lines in production mode
ini_set('display_errors','on');
error_reporting(E_ALL);
// Apns config
// true - use apns in production mode
// false - use apns in dev mode
define("PRODUCTION_MODE",false);
$serverId = 1;
$serverName = 'my-server-domain.com';
if(PRODUCTION_MODE) {
$apnsHost = 'gateway.sandbox.push.apple.com';
} else {
$apnsHost = 'gateway.push.apple.com';
}
$apnsPort = 2195;
if(PRODUCTION_MODE) {
// Use a development push certificate
$apnsCert = $_SERVER['DOCUMENT_ROOT'].'/apns/apns-dominos-development.pem';
} else {
// Use a production push certificate
$apnsCert = $_SERVER['DOCUMENT_ROOT'].'/apns/apns-dominos-production.pem';
}
// --- Sending push notification ---
// Insert your device token here
$device_token = "<dc6127d8 dc6127d8 dc6127d8 dc6127d8 dc6127d8 dc6127d8 dc6127d8 dc6127d8>"; // Some Device Token
// Notification content
$payload = array();
//Basic message
$payload['aps'] = array(
'alert' => 'testing 1,2,3..',
'badge' => 1,
'sound' => 'default',
);
$payload['server'] = array(
'serverId' => $serverId,
'name' => $serverName
);
// Add some custom data to notification
$payload['data'] = array(
'foo' => "bar"
);
$payload = json_encode($payload);
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', "");
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
$deviceToken = str_replace(" ","",substr($device_token,1,-1));
echo $deviceToken;
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(mb_strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
//socket_close($apns);
fclose($apns);
?>
答案 1 :(得分:2)
在服务器端实施反馈服务,并在服务器端检查所有设备令牌发送到APNS的持续时间。 从反馈服务至少你会知道有多少设备收到你的通知。 如果所有设备令牌一个接一个地发送到APN,并且APN没有通过反馈服务发送任何列表,那么你无法处理在设备上接收通知的持续时间。
答案 2 :(得分:2)
好的,我终于得到了我的问题。问题不在代码实际上问题是在我的iPhone中设置错误的DNS值。 Iphone自动将我的路由器的ip放入DNS字段。现在我给我的服务提供商的DNS值,然后它工作正常。现在我收到推送消息后立即发送。
我希望它可以帮助他人。
答案 3 :(得分:1)
检查您的推送通知证书。证书是否与任何私钥相关联?
如果不是,请使用从您的密钥链生成的适当私钥重新创建推送通知证书。
请查看以下教程:
Apple Push Notification Tutorial:
感谢,
MinuMaster
答案 4 :(得分:1)
使用UrbanAirShip。在我看来,它是最好的服务器端解决方案,因为它包括Android(C2DM)和Blakberry的推送式通知。
尝试找出这些文件之间的差异并理解它们。可能是你的问题的解决方案。这是我的代码:
<?php
$message = 'Hello'; // $_GET or $_POST
$badge = 3; // int
$sound = 'default'; // string - sound name
$development = true; // boolean
$payload = array();
$payload['aps'] = array('alert' => $message, 'badge' => intval($badge), 'sound' => $sound);
$payload = json_encode($payload);
$apns_url = NULL; // Set Later
$apns_cert = NULL; // Set Later
$apns_port = 2195;
if($development)
{
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = '/path/apns.pem'; // relative address to an App Specific Certificate file
}
else
{
$apns_url = 'gateway.push.apple.com';
$apns_cert = '/path/cert-prod.pem';
}
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl','local_cert',$apns_cert);
$apns = stream_socket_client('ssl://'.$apns_url.':'.$apns_port,$error,$error_string,2,STREAM_CLIENT _CONNECT,$stream_context);
// You will need to put your device tokens into the $device_tokens array yourself
$device_tokens = array(); // tokens!!!
foreach($device_tokens as $device_token)
{
$apns_message = chr(0).chr(0).chr(32).pack('H*',str_replace(' ','',$device_token)).chr(0).chr(strlen($payload)).$payload;
fwrite($apns, $apns_message);
}
@socket_close($apns);
@fclose($apns);
?>