Сообщения APN доставляются, но не принимаются на устройстве iOS

Я настроил службу пересылки / отправки, которая содержит открытое соединение с APN, как указано / рекомендовано Apple, чтобы предотвратить обнаружение DoS и сертификат работает …

Я успешно подключен, и сообщения отправляются успешно, но сообщения не принимаются на устройстве iOS (iPhone) … (?!?) Количество отправленных байт равно количеству (байтов) возвратов fwrite.

Наконец, сообщения могут содержать специфичные для страны символы. Как APN обрабатывают это? и как эти символы должны быть отправлены на сервер APN?

Я пробовал как с, так и без службы пересылки, но без везения. 🙁

Все вызовы журнала удаляются в фрагментах кода, чтобы избежать путаницы. Это означает, что вложенные сообщения журнала не могут отображаться непосредственно в фрагменты кода, но должно быть возможно «угадать», откуда приходят сообщения журнала.

Пожалуйста, помогите мне в решении этих вопросов. заранее спасибо

Соединение выполняется таким образом:

$ctx = stream_context_create(); stream_context_set_option($ctx, 'ssl', 'local_cert', $certPath); stream_context_set_option($ctx, 'ssl', 'passphrase', $passPhrase); $this->apn_link = stream_socket_client($url, $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx); /* ... */ 

Внутри цикла, который прослушивает сокет в службе пересылки:

 foreach ($changed as $changed_socket) { while(isset($changed_socket) && socket_recv($changed_socket, $buf, 1024, 0) >= 1) { $buf = trim($buf); if ($buf != '') { $this->msg2apn($buf); } } } /* ... */ 

Далее я отправляю сообщения таким образом:

 public function msg2apn($msg) { if (isset($this->apn_link)) { while(!$result = fwrite($this->apn_link, $msg, strlen($msg))) { usleep(400000); //400 msec } if ($result) { fflush($this->apn_link); return True; } } } 

Сообщения, отправленные в экспедиторскую службу:

 private function send_pn_iosproxy($msg) { $address = IOS_APNPROXY_HOST; $port = IOS_APNPROXY_PORT; $fp = fsockopen($address,$port); if (!$fp) { elog("Connection to [".$address.":".$port."] could not be established"); return False; } $result = fwrite($fp, $msg, strlen($msg)); if (isset($fp)) fflush($fp); if (isset($fp)) fclose($fp); return True; } 

Для каждого токена устройства сообщение генерируется следующим образом:

 $payload = '{"aps":{"alert":"'.$message['message'].'","badge" : "1","sound":"default"}}'; foreach($deviceTokens as $deviceToken) { // Build the binary notification $msg = chr(0) . pack('n', 32) . base64_decode($deviceToken) . pack('n', strlen($payload)) . $payload; // see function above $result = $this->send_pn_iosproxy($msg); if ($result) { ilog("Message delivered"); dlog("DeviceToken[$deviceToken], Payload[$payload]"); } else { wlog("Message not properly delivered"); dlog("Msg[$msg]"); dlog("DeviceToken[$deviceToken], Payload[$payload]"); } } 

Журнальные сообщения из logdisp находятся в службе пересылки, а сообщения журнала из журнала – с веб-сервера. Веб-сервер подключается к службе пересылки с использованием 127.0.0.1/localhost, поэтому веб-сервер и сервер пересылки размещаются на одном физическом компьютере.

 [2015-08-27 11:19:03] log.DEBUG: pn::send_pn_ios() [] [] [2015-08-27 11:19:03] log.DEBUG: pn::send_pn_iosproxy() [] [] [2015-08-27 11:19:03] log.INFO: Message delivered [] [] [2015-08-27 11:19:03] logdisp.DEBUG: Client [127.0.0.1] connected [] [] [2015-08-27 11:19:03] log.DEBUG: DeviceToken[djYBbJepT8NOPKgLd5FoGOog9jxY8LcpQhCGaXAkqy0=], Payload[{"aps":{"alert":"message","badge" : "1","sound":"default"}}] [] [] [2015-08-27 11:19:03] logdisp.DEBUG: Message buf[...{"aps":{"alert":"message","badge" : "1","sound":"default"}}] from ip[127.0.0.1] [] [] [2015-08-27 11:19:03] log.DEBUG: pn::send_pn_iosproxy() [] [] [2015-08-27 11:19:03] logdisp.DEBUG: dispatcher::msg2apn() [] [] [2015-08-27 11:19:03] log.INFO: Message delivered [] [] [2015-08-27 11:19:03] logdisp.DEBUG: SUCCESS msg2apn, written[107], sent[107] [] [] [2015-08-27 11:19:03] log.DEBUG: DeviceToken[7FH3vRMfmb3qRBOaKY30GT/+82jU/6kx7RhBJq2Ihw8=], Payload[{"aps":{"alert":"message","badge" : "1","sound":"default"}}] [] [] [2015-08-27 11:19:03] log.DEBUG: pn::send_pn_iosproxy() [] [] [2015-08-27 11:19:03] log.INFO: Message delivered [] [] [2015-08-27 11:19:03] log.DEBUG: DeviceToken[b+20wASQBp9lD08l1+EY3CHJjcCl1UBWNmSeI1c9ouQ=], Payload[{"aps":{"alert":"message","badge" : "1","sound":"default"}}] [] [] [2015-08-27 11:19:03] log.DEBUG: pn::send_pn_iosproxy() [] [] [2015-08-27 11:19:03] log.INFO: Message delivered [] [] [2015-08-27 11:19:03] log.DEBUG: DeviceToken[Yya0lH080lz6fL2B/1UexOenBLyAJIp3zgSGgV9F5ms=], Payload[{"aps":{"alert":"message","badge" : "1","sound":"default"}}] [] [] [2015-08-27 11:19:04] logdisp.DEBUG: Client [127.0.0.1] connected [] [] [2015-08-27 11:19:04] logdisp.DEBUG: Message buf[...{"aps":{"alert":"message","badge" : "1","sound":"default"}}] from ip[127.0.0.1] [] [] [2015-08-27 11:19:04] logdisp.DEBUG: dispatcher::msg2apn() [] [] [2015-08-27 11:19:04] logdisp.DEBUG: SUCCESS msg2apn, written[107], sent[107] [] [] [2015-08-27 11:19:05] logdisp.DEBUG: Client [127.0.0.1] connected [] [] [2015-08-27 11:19:05] logdisp.DEBUG: Message buf[...{"aps":{"alert":"message","badge" : "1","sound":"default"}}] from ip[127.0.0.1] [] [] [2015-08-27 11:19:05] logdisp.DEBUG: dispatcher::msg2apn() [] [] [2015-08-27 11:19:05] logdisp.DEBUG: SUCCESS msg2apn, written[107], sent[107] [] [] [2015-08-27 11:19:07] logdisp.DEBUG: Client [127.0.0.1] connected [] [] [2015-08-27 11:19:07] logdisp.DEBUG: Message buf[...{"aps":{"alert":"message","badge" : "1","sound":"default"}}] from ip[127.0.0.1] [] [] [2015-08-27 11:19:07] logdisp.DEBUG: dispatcher::msg2apn() [] [] [2015-08-27 11:19:07] logdisp.DEBUG: SUCCESS msg2apn, written[107], sent[107] [] [] 

Я попытался отправить два вида полезной нагрузки:

 {"aps" : {"alert" : "message","badge" : "1","sound" : "default"}} {"aps" : { "alert" : { "title" : "My Title", "body" : "My Message" }, "badge" : 2, "sound" : "default" } } 

После восстановления сертификатов теперь я получаю следующие ошибки при подключении:

 [vagrant@server backend-src]$ php -f dispatcher.php Log path: [/srv/backend/log/log.txt], Log level: [0], Binding info: address[127.0.0.1], port[6060] Connecting to [ssl://gateway.push.apple.com:2195], using certificate [/srv/backend/htdocs/ios_distribution.pem] and passphrase[?] PHP Warning: stream_socket_client(): Failed to enable crypto in /vagrant/backend-src/dispatcher.php on line 182 PHP Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in /vagrant/backend-src/dispatcher.php on line 182 Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in /vagrant/backend-src/dispatcher.php on line 182 Connect failed error[0 ] to url [ssl://gateway.push.apple.com:2195] with certicate [/srv/backend/htdocs/ios_distribution.pem] 

Теперь я могу подключиться! Причина здесь была простой. Путь к сертификатам был неправильным. Однако push-уведомления по-прежнему не принимаются на устройствах с новым сертификатом.

Должно ли приложение быть опубликовано / выпущено с новым сертификатом, прежде чем он будет работать? Ни по разработке, ни по производству не поступают сообщения на устройстве ???

Наконец, ему удалось получить сообщения как для песочницы, так и для производственных / рекламных токенов.

 // 64 chars token // Sandbox and productions tokens have the same length and // they cannot be distinguished $deviceToken='1234567890123456789012345678901234567890123456789012345678901234'; $body['aps'] = array('alert' => 'Sample message', 'sound' => 'default'); $payload = json_encode($body); $deviceToken = str_replace(' ', '', $deviceToken); $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; fwrite($apn_link, $msg, strlen($msg)); fflush($apn_link); 

НЕ смешивайте маркеры из песочницы и продуктового устройства на производстве!

Производственная среда APN не позволяет использовать маркеры песочницы, и она молча перестает доставлять сообщения в токены производства, когда используется токен песочницы.

Solutions Collecting From Web of "Сообщения APN доставляются, но не принимаются на устройстве iOS"

 // 64 chars token // Sandbox and productions tokens have the same length and // they cannot be distinguished $deviceToken='1234567890123456789012345678901234567890123456789012345678901234'; $body['aps'] = array('alert' => 'Sample message', 'sound' => 'default'); $payload = json_encode($body); $deviceToken = str_replace(' ', '', $deviceToken); $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; fwrite($apn_link, $msg, strlen($msg)); fflush($apn_link); 

НЕ смешивайте маркеры для песочницы и устройства для производства на производстве!

Производственная среда APN не позволяет использовать маркеры песочницы, и она молча перестает доставлять сообщения в токены производства, когда используется токен песочницы.

Apple немного изменила ситуацию: в то время как она по-прежнему позволяет создавать сертификаты только для песочницы, производственные сертификаты могут использоваться как в песочнице, так и в производственных средах.