【问题标题】:APNS not sending response nor sending push notificationAPNS 不发送响应也不发送推送通知
【发布时间】:2012-11-02 21:01:43
【问题描述】:

Apple's docs 这么说:

“如果您发送通知并且 APNs 发现通知格式错误或无法理解,它会在断开连接之前返回错误响应数据包。(如果没有错误,APNs 不会返回任何内容。)图 5-3 描述错误响应包的格式。"

这让我相信,APNS 不会发回某些内容的唯一原因是我发送给他们的内容格式是否正确。但是,当我尝试为他们的响应而担心时,我得到一个长度为 0 的字符串,并且当 unpacked 变为 null 时,我认为这意味着没有任何内容被写回给我。

我的流是由stream_socket_client() 打开的,并且没有返回 false 或抛出异常。我知道我的 fwrite 也成功地向该流写入了 154 个字节。为什么苹果没有回应?

这是连接APNS的代码:

function openConnection() {
    $streamContext = stream_context_create();
    stream_context_set_option($streamContext, 'ssl', 'local_cert', $this->APNS_CERT);
    stream_context_set_option($streamContext, 'ssl', 'passphrase', $this->Password);
    $apns = stream_socket_client('ssl://' . $this -> APNS_HOST . ':' . $this -> APNS_PORT, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
    return $apns;
}

那么,在调用openConnection之后的下一个方法中:

//open the connection to use with apple.
$apns = $this->openConnection();

$alert = $message['alert'];
$badge = $message['badge'];
$deviceToken = $message['deviceToken'];

$payload['aps'] = array(
    'alert' => $message['alert'],
    'badge' => $message['badge'],
    'sound' => $message['sound']
);

if ($message['extraPayload'] != null) {
    $payload['acme'] = $message['extraPayload'];
}

$encodedString = json_encode($payload);

//create message
$apnsMessage = chr(1) . pack("N", $message['identifier']) . pack("N", $message['expire']) . pack("n", 32) . pack('H*', str_replace(' ', '', $message['deviceToken'])) . pack("n",strlen($encodedString)) . $encodedString;

$write = fwrite($apns, $apnsMessage);
echo $write;
//the echo was just to see if it wrote.

if (!$apns) {
    socket_close($apns);
    fclose($apns);

    echo "connection to APNS was lost.";
}


//look for changes. $null=null because some bug doesn't just let you pass null.
$null = null;
$changedStreams = stream_select($streamArray, $null, $null, 0, 1000000);

//check if it is actually false
if ($changedStreams === false) {
    //close stream when done.
    socket_close($apns);
    fclose($apns);

    echo "No response from APNs";
} elseif ($changedStreams > 0) {
//then check if what they sent back is an error and grab the error packet
$responseBinary = fread($apns, 6);
var_dump($responseBinary);

//check that it's the right thing
if ($responseBinary != false || strlen($responseBinary) == 6) {
    //convert it from it's binary stream state and print.
    $response = unpack('Ccommand/Cstatus_code/Nidentifier', $responseBinary);
    var_dump($response);

    //close stream when done.
    socket_close($apns);
    fclose($apns);
    }
} else {
    echo "Apple failed to respond, message was not sent.";
}

最后的var_dump是NULL。

编辑:

原来这是一个凭据冲突的错误。通过创建一个新的 pem 文件解决了这个问题。

【问题讨论】:

  • 在回答您发布的另一个问题时,我不是在应用程序方面工作的开发人员,所以我不知道细节,但他说这是一个临时版本该应用程序,我们没有使用沙盒,我认为这是正确的。
  • 请注意,下面说 fread 不能用于 APNs (stackoverflow.com/questions/1278834/…)
  • 谢谢,我稍微修改了我的代码,虽然它没有改变 NULL 响应。我将再次与 ios 开发人员交谈,并仔细检查 pem、应用程序版本等。
  • fyi APNS 沙箱服务器在出错时不会返回任何数据。只需关闭连接即可。尝试使用生产服务器。

标签: php stream push apple-push-notifications


【解决方案1】:

从那个页面:

您应该定期与反馈网络服务器连接,并获取那些反复报告失败交付尝试的设备的当前列表。然后您应该停止向与这些应用程序关联的设备发送通知。有关详细信息,请参阅“反馈服务”。

反馈服务

通过类似于用于发送推送通知的二进制接口访问反馈服务。您通过feedback.push.apple.com,端口2196访问生产反馈服务;您可以通过 feedback.sandbox.push.apple.com 的 2196 端口访问沙盒反馈服务。与推送通知的二进制接口一样,您必须使用 TLS(或 SSL)来建立安全的通信通道。这些连接所需的 SSL 证书与为发送通知而配置的证书相同。要建立受信任的提供者身份,您应该在连接时使用点对点身份验证将此证书提供给 APN。

【讨论】:

  • 该服务不只是用于删除因用户删除应用程序而过期的设备令牌吗?我尝试使用的设备令牌仅在 2 天前提供给 Web 服务。
  • 据我所知,了解失败原因的唯一方法是反馈服务
  • 好的,谢谢您的回复。我要去试试,然后发布结果。
  • 也许我做错了,因为这也产生了一个空字符串。我将编辑我的原始帖子以包含一些代码。
  • 嘿,只是想让您知道我们创建了一个新的 pem 文件,现在脚本在其原始状态下运行良好。我猜这个错误只是混乱造成的。
猜你喜欢
  • 2015-12-29
  • 2013-06-10
  • 2011-06-07
  • 2012-02-22
  • 2018-11-27
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多