发送voip推送通知后是否应关闭与APN的连接?

Ala*_*rpa 7 apple-push-notifications ios swift

我正在使用simplepush.php脚本将voip推送从用户发送给用户.我的应用程序可能会根据获取的用户数量来完成许多推送请求.我发现的simplepush.php的每个例子似乎都在最后明确地关闭了连接 - 这是我的脚本(见最后一行):

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'voip.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client($apnsUrl, $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'
    );

$body['info'] = array(
  'roomname' => $roomName,
  'uuid' => $uuid
  );

// 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));

if (!$result)
    echo 'Message not delivered' . PHP_EOL;
else
    echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);
Run Code Online (Sandbox Code Playgroud)

请注意:我使用旧版APNs二进制接口发送通知而不是HTTP/2请求,因为所有simplepush脚本都使用它.我不熟悉PHP,但似乎脚本在每次调用结束时关闭连接:fclose($fp);

但根据Apple,我应该保持连接打开:

管理连接的最佳实践通过多个通知保持与APN的连接; 不要反复打开和关闭连接.APN将快速连接和断开视为拒绝服务攻击. https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW6

但由于我使用的是传统的二进制接口,我是否应该在每次通话后关闭连接?或者我误解了fclose($fp);这里的功能?使用这个二进制文件时处理连接的适当方式的任何清晰度将非常感激!

fre*_*dpi 3

解释

\n\n

据我所知,不要关闭每个通知的连接的建议来自批量通知传递区域,其中许多用户都会传递相同的通知。

\n\n

除了可能被解释为攻击之外,一直关闭和重新打开是非常低效的,并且会导致巨大的交付延迟。仅在流上写入二进制消息比打开和关闭每个通知要快得多。看这个例子:

\n\n
// Open a connection to the apns server (this code is the same as a few lines below, so if changed here, also change there)\n$stream_context = stream_context_create();\nstream_context_set_option($stream_context, \'ssl\', \'local_cert\', \'voip.pem\');\nstream_context_set_option($stream_context, \'ssl\', \'passphrase\', \'secret_pass\');\n$apns = stream_socket_client($url, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $stream_context);\n\n// Return if connection is impossible\nif (!$apns) { return; }\n\n// Create payload body\n$body[\'aps\'] = array(\n    \'alert\' => $title,\n    \'badge\' => 1\n);\n\n// Encode the payload as json\n$payload = json_encode($body);\n\n// Iterate through token array\nforeach($tokens as $token) {    \n    $user_id = 2 // Random id ;)\n\n    // Build binary notification\n    $msg = pack("C", 1);\n    $msg .= pack("N", $user_id);\n    $msg .= pack("N", $notification_expiration_date);\n    $msg .= pack("n", 32);\n    $msg .= pack(\'H*\', $token);\n    $msg .= pack("n", strlen($payload));\n    $msg .= $payload;\n\n    // Send to the server\n    $fwrite_result = fwrite($apns, $msg, strlen($msg));\n}\n\nfclose($apns);\n
Run Code Online (Sandbox Code Playgroud)\n\n

看看它如何打开一个连接,为数组中的每个标记写入,然后关闭,而不是每次都打开、写入和关闭。

\n\n

以批量推送应用程序为例,现在由您的设计决定是否应保留连接。如果您每小时发送一次通知,我认为打开和关闭每个通知是合适的。但是,如果您每分钟有多个通知的吞吐量,则需要保持连接打开。

\n\n

建议

\n\n

您可以采取的一种方法是在完成现有队列后查找要传递的任何新通知。如果没有,您可以再等待几分钟,然后再次检查并关闭连接,如果仍然没有新的内容,如果有,则保持打开状态并使用同一连接发送新通知。

\n\n

这符合 Apple 的建议:

\n\n
\n

您应该让连接保持打开状态,除非您知道它会在很长一段时间内处于空闲状态\xe2\x80\x94例如,如果您每天只向用户发送一次通知,那么每天使用一个新连接是可以接受的做法。

\n
\n\n

警告

\n\n

使用单个连接时需要考虑的一件重要事情是错误处理:无效的令牌(生产/沙盒模式混淆)可能会导致连接在您不注意的情况下关闭,但还有其他帖子进一步讨论了这一点。

\n