2

在过去的 3 天里,我一直在尝试让我的 php 代码和 apns 工作。

到目前为止,我能够发送通知(我只有一个设备,所以我不知道这是否适用于多个设备)。

当我尝试测试为 2 个设备发送一个通知时,其中第一个是设备令牌无效(由我发明),第二个是我的设备令牌,我无法将通知发送到我的设备......从我读到的内容来看,当通知不可读或错误,apns 关闭连接并发送 6 个字节长的错误,其中第 2 个字节(status_code)是错误类型。如果没有发生错误,我仍然无法理解 apns 是发送 status_code 0(没有遇到错误)还是根本没有发送任何内容。

到目前为止,尽管在互联网上找到了几个代码,但我还是找不到这个 status_code。

代码

$ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'local_cert', '.\certif\ck.pem');
    stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Create the payload body
    //file_put_contents('logs/debug_not.log', 'body'. "\n", FILE_APPEND);
    $body['aps'] = array(
        'alert' => $message,
        'sound' => 'default'
    );

    // Encode the payload as JSON
    //file_put_contents('logs/debug_not.log', 'json body'. "\n", FILE_APPEND);
    $payload = json_encode($body);
    $open = true;
    foreach ($devices as $device) {
        //file_put_contents('logs/debug_not.log', 'inicio ciclo'. "\n", FILE_APPEND);
        if($open == true){
            //file_put_contents('logs/debug_not.log', 'abrir ligacao'. "\n", FILE_APPEND);
            // 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){
               //file_put_contents('logs/debug_not.log', 'erro abrir ligacao'. "\n", FILE_APPEND);
               throw new \Exception;
            }
        }
        // Build the binary notification
        //file_put_contents('logs/debug_not.log', 'criar payload'. "\n", FILE_APPEND);
        $msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $device['token'])) . pack('n', strlen($payload)) . $payload;


        // Send it to the server
        //file_put_contents('logs/debug_not.log', 'enviar payload'. "\n", FILE_APPEND);
        $result = fwrite($fp, $msg, strlen($msg));
        stream_set_blocking ($fp, 0);    

        $errorResponse = @fread($apns, 6);
        //if i var_dump($errorResponse) it gives me null/false all the time, no matter what             

        //this is my workaround for invalid device tokens-- its not working or at least is not send the valid tokens
        if(!$result || !$fp)
        {

            //file_put_contents('logs/debug_not.log', 'erro na not '. chr($data["status_code"]). "\n", FILE_APPEND);
            fclose($fp);
            $open = true;
        } else{
            //file_put_contents('logs/debug_not.log', 'suc na not'. "\n", FILE_APPEND);
            $open = false;
        }
        //file_put_contents('logs/debug_not.log', 'fim ciclo'. "\n", FILE_APPEND);
    }
    // Close the connection to the server
    if($fp){
        //file_put_contents('logs/debug_not.log', 'fechar connection'. "\n", FILE_APPEND);
        fclose($fp);
    }

我的连接上的 fread 始终给出 null/false,即使我收到通知或尝试使用错误的令牌也是如此。

我的错误后连接逻辑似乎不起作用。

可以请人帮助我吗???我不打算使用第 3 类或代码,希望有一个简单的基本类用于一组设备令牌,即使有一些 apns 给出错误。

感谢大家。

4

2 回答 2

6

您已将连接设为$fp = stream_socket_client ......

并且您正在尝试$errorResponse = @fread($apns, 6);哪个永远不会给您任何输出,因为 $apns 未定义。

相反,您应该这样做:

$errorResponse = @fread($fp, 6);

你的代码可以正常工作

于 2015-07-20T06:49:56.863 回答
1

如果您收到错误消息(很可能是因为您发明的设备令牌在您的应用程序的 Apple 服务器上不存在),则在连接关闭之前返回错误消息。如果消息成功,则没有响应,但连接保持打开状态。

以下是您可以处理的方法:

  1. 发送您的信息。
  2. 超时读取错误(或在非阻塞模式下)。如果您收到错误响应,则消息失败。(你需要一个新的连接。)
  3. 如果读取超时(或在非阻塞模式下不返回任何内容),则消息可能成功。(没做什么。)
  4. 发送下一条消息。如果发送成功(仍然连接),最后一条消息肯定是成功的。

跟踪您最后一条成功的消息。您始终可以通过向您自己的设备发送消息来跟踪一系列消息,以防止任何误报。

您可能想查看EasyAPNS的源代码,这是一个开源的 PHP 实现。此外,您可以阅读 Apple 文档中的详细信息:Provider Communication with Apple Push Notification Service

于 2013-08-22T19:34:13.977 回答