【问题标题】:Push Notifications for multiple Apps from one server从一台服务器推送多个应用程序的通知
【发布时间】:2015-12-29 13:54:33
【问题描述】:

我使用RMSPushNotificationsBundle 处理推送通知。我正在从一台服务器向多个应用程序发送 pushNotifications。我正在使用 setAPNSPemAsString 方法来选择正确的证书。但推送通知仅在第一次发送。谁能告诉我为什么?谢谢!

public function sendIOS($appName){
    $notifications = $this->container->get('rms_push_notifications');

    $message = new iOSMessage();
    $message->setMessage($this->message);
    $message->setData($this->getData());
    $message->setAPSSound("default");
    $message->setDeviceIdentifier($this->pushToken);

    if ($appName !="appName") {
        $pemFile    = $this->container->getParameter("rms_push_notifications.ios.".$appName.".pem");
        $passphrase = $this->container->getParameter("rms_push_notifications.ios.".$appName.".passphrase");

            $pemContent = file_get_contents($pemFile);
            $notifications->setAPNSPemAsString($pemContent, $passphrase);
    }
    return $notifications->send($message);
}

【问题讨论】:

  • 日志中有任何内容吗?另外,$appName 设置在哪里?
  • with appName 只是我们用来决定使用哪个证书进行推送通知的一个变量。通过 appName,我们知道我们的应用程序用户在他的手机上使用的版本。使用 setAPNSPemAsString 函数只工作一次,在其他发送函数上的第一次推送通知返回我们 false..
  • 对于 IOS,捆绑包包括反馈服务。也许你可以在这里找到答案。你看见了吗? github.com/richsage/…
  • 1.您确定 $appName 每次都是正确的吗? 2. 仅第一次是什么意思……它是在一个脚本运行中还是在循环中调用了不止一次。 3. 你尝试发送多少个通知,1-10、100-1000?
  • 您是说它适用于 1 次推送到 1 台设备然后就死机了吗?

标签: php symfony push-notification apple-push-notifications


【解决方案1】:

我不确定是什么问题,但遵循小代码对我有用。至少您可以使用它来测试与 APNS 服务器的连接。

<?php
// your private key's passphrase
$passphrase = $_POST('passphrase');

$pemFilesPath = 'path/to/pem/folder/';

// path to pem file
$appCert = $_POST('pemfile');

$pemFile = $pemFilePath.$appCert;

$notifications = $_POST('notifications');

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $pemFile);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// 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)
    exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

$records = 0;

foreach ($notifications as $deviceToken => $message)
{
    // Create the payload body
    $body['aps'] = array(
        'alert' => $message,
        'sound' => 'default'
        );

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

    if (!$fp) {
        exit("Connection intruptted " . E_USER_ERROR . PHP_EOL);
    }
    // Send it to the server
    $result = fwrite($fp, $msg, strlen($msg));
    if(!$result) {

                                print_r("Failed writing to stream.", E_USER_ERROR);
                                fclose($fp);
                                die;
                        }
                     /* uncomment this part for troubleshooting   
                        else {
                                $tv_sec = 1;
                                $tv_usec = null; // Timeout. 1 million micro seconds = 1 second
                                $read = array($fp); $we = null; // Temporaries. "Only variables can be passed as reference."
                                $numChanged = stream_select($read, $we, $we, $tv_sec, $tv_usec);
                                if(false===$numChanged) {
                                        print_r("Failed selecting stream to read.", E_USER_ERROR);
                                        fclose($fp);
                                        die;
                                }
                                else if($numChanged>0) {
                                        $command = ord(fread($fp, 1));
                                        $status = ord(fread($fp, 1));
                                        $identifier = implode('', unpack("N", fread($fp, 4)));
                                        $statusDesc = array(
                                                0 => 'No errors encountered',
                                                1 => 'Processing error',
                                                2 => 'Missing device token',
                                                3 => 'Missing topic',
                                                4 => 'Missing payload',
                                                5 => 'Invalid token size',
                                                6 => 'Invalid topic size',
                                                7 => 'Invalid payload size',
                                                8 => 'Invalid token',
                                                255 => 'None (unknown)',
                                        );
                                        print_r("APNS responded with command($command) status($status) pid($identifier).", E_USER_NOTICE);

                                        if($status>0) {
                                                $desc = isset($statusDesc[$status])?$statusDesc[$status]: 'Unknown';
                                                print_r("APNS responded with error for pid($identifier). status($status: $desc)", E_USER_ERROR);
                                                // The socket has also been closed. Cause reopening in the loop outside.
                                                fclose($fp);
                                                die;
                                        }
                                        else {
                                                // Apple docs state that it doesn't return anything on success though
                                               $records++;
                                        }
                                } else {
                                        $records++;
                                }
                        }
                        */  
    $records++;
    }

echo "Send notifications to $records devices";
// Close the connection to the server
fclose($fp);

?>

注意:很久以前写过这个小代码,它运行良好。我现在不记得出处了,但是有一个教程。最近没有测试,所以你可能需要修改它。 一些建议:

  1. 打开连接并将所有通知写入服务器,然后将其关闭。
  2. 读取服务器响应会减少功能,但有利于故障排除和启动。因此,请根据需要使用该部分。
  3. 查看此文档了解更多错误说明APNs Provider API

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多