在 PHP 中,通过 APNS 的 SSL 通道发送的 APNS 有效负载结构是这样生成的:
$payment = chr(0) . pack('n', 32) . pack('H*', $device_token) . pack('n', strlen($data)) . $data;
哪里:
-
$device_token
是由 APNS 生成和响应的 64 个字符的设备令牌 -
$data
是一个 JSON 编码的数组,包含 APNS 内容的参数(例如消息(
这种结构设计背后的原因是什么?
函数 chr(( 返回一个包含 ascii 指定的字符的单字符字符串。但是chr(0)
不会返回可见字符,证明如下:
echo '['.chr(0).']'; // which prints []
接下来,连续的 3 个 pack(( 函数:
- 第一个返回空格
pack('n', 32)
- 第二个
pack('H*', $device_token)
返回设备令牌的十六进制二进制表示形式 - 第三个
pack('n', strlen($data))
返回一个不可见字符,证明如下:
$data = array(
'message' => '12345678',
);
$data = json_encode($data);
echo '[' .pack('n', strlen($data)) . ']'; // which returns []
最后一个是 JSON 编码的内容。
苹果为什么要设计这种结构?那些看不见的角色是干什么用的?
第一个chr(0)
返回一个包含 0 的字节。它标识您正在使用的二进制格式。 0
用于简单格式,1
用于增强格式(包括消息标识符和过期时间(,2
用于他们在 iOS7 中引入的较新格式。
pack('n', 32)
返回以两个字节编码的数字 32。它表示设备令牌的大小(以字节为单位(。在这种情况下,我不确定为什么它们需要两个字节,因为32
可以存储在一个字节中(并且设备令牌的大小始终为 32,所以也许这个字段并不是真的必要(。
pack('H*', $device_token)
将设备令牌的十六进制表示形式打包为 32 字节二进制表示形式。这比发送 64 字节十六进制表示更有效。
Third one pack('n', strlen($data))
返回以两个字节编码的有效负载的长度。由于有效负载的长度通常<256(256 是限制(,因此这两个字节中的第一个通常包含 0
。
那些invisible characters
根本不是角色。它们是描述通知的数字。
您可以在此处阅读有关简单二进制格式的更多信息。