APNS在不活动后无法发送消息

时间:2015-11-22 12:10:10

标签: php apple-push-notifications

我已经在PHP中为APNS创建了一个客户端 - 服务器解决方案。

“服务器”是一个连续运行的脚本,它等待连接并将内容复制到APNS。这意味着它始终保持与APNS的连接。我这样使用fwrite和stream context。这是接受传入连接的部分:

if ($client = @stream_socket_accept($this->socket, -1)) {

   $this->writeLine("Received connection.");

   $this->inputBuffer = stream_get_contents($client);

}

它在while循环中运行,因此下一次迭代会将inputBuffer的内容复制到APNS:

$writtenBytes = @fwrite($this->connectionAPNS, $this->inputBuffer, strlen($this->inputBuffer));
然后我检查写的字节如下:

if ($writtenBytes > 0) {

$this->writeLine("Copied $writtenBytes bytes to APNS.");

   return true;
}

现在,当连接闲置一段时间时会出现问题。第一个推送通知将返回写入APNS的字节数 - 例如“复制157个字节到APNS。”,表示fwrite工作,但邮件未送达。

然后下一个通知返回0字节写入,自动重新连接(我的脚本的一部分)并写入失败的字节 - 然后它工作。

如果连接实际上无法写入或者APNS不接受它们,为什么我会返回写入的字节?

我使用增强的通知格式,并检查返回的错误,似乎没有。

我使用这个代码,我在博客上发现,在写完APNS后我将连接句柄传递给函数:

function checkAppleErrorResponse($fp)
{
    $apple_error_response = fread($fp, 6);

    if ($apple_error_response) {

        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 {
            // Here is some fancy if/else error handling, but I never end in this else , so I excluded it.

        }
     }
}

保持连接APNS打开的'client'部分看起来像这样,只要writeBytes返回0(错误)或脚本首次加载时调用:

function connectToAPNS()
    {

        $ctx = stream_context_create();
        stream_context_set_option($ctx, 'ssl', 'local_cert', $this->certpath);
        stream_context_set_option($ctx, 'ssl', 'passphrase', $this->passphrase);


        // Open a connection to the APNS server
        $error = "";
        $errno = 0;
        $this->connectionAPNS = stream_socket_client(
            'ssl://gateway.push.apple.com:2195',
            $errno,
            $error,
            60,
            STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT,
            $ctx
        );

        if ($this->connectionAPNS) {
            stream_set_blocking($this->connectionAPNS, 0);
            $this->writeLine("Connected to APNS!");

            return true;
        } 
    }

1 个答案:

答案 0 :(得分:0)

您的应用是发布版还是调试版?在每种情况下,您都必须与不同的Web服务进行通信并使用不同的证书。

在沙盒/调试模式下与 ssl://gateway.sandbox.push.apple.com进行通信:2195

在生产/重新模式下与 ssl://gateway.push.apple.com:2195 进行沟通

如果您使用错误的服务进行通信,将以静默方式删除通知。