2015-12-22 34 views
0

的高容量我需要发送数以千计(实际上是10 000)的同时推送通知,要做到这一点,我查的StackOverflow,发现这两个问题:发送通知

我使用PHP来实现我的推送系统:

// Create the payload body 
    $body['aps'] = [ 
     'alert' => $notification->getMessage(),//$notification is just a notification model, where getMessage() returns the message I want to send as string 
     'sound' => 'default' 
    ]; 

    // Encode the payload as JSON 
    $payload = json_encode($body); 

    $fp = self::createSocket(); 
    foreach($devices as $device) { 
     $token = $device->getToken(); 
     $msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $token)) . pack('n', strlen($payload)) . $payload; 
     if(!self::sendSSLMessage($fp, $msg)){ 
     //$msg is a parameter of the method, it's the message as string 
      fclose($fp); 
      $fp = self::createSocket(); 
     }else{ 
      //Here I log "n notification sent" every 100 notifications 
     } 
    } 
    fclose($fp); 

这里是createSocket()方法:

private static function createSocket(){ 
    $ctx = stream_context_create(); 
    stream_context_set_option($ctx, 'ssl', 'local_cert', PUSH_IOS_CERTIFICAT_LOCATION); 
    stream_context_set_option($ctx, 'ssl', 'passphrase', PUSH_IOS_PARAPHRASE); 
    // Open a connection to the APNS server 
    $fp = stream_socket_client(
     'ssl://gateway.push.apple.com:2195', $err, 
     $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); 
    stream_set_blocking ($fp, 0); 
    if (!$fp) { 
     FileLog::log("Ios failed to connect: $err $errstr"); 
    } 
    return $fp; 
} 

而且sendSSLMessage()方法:

private static function sendSSLMessage($fp, $msg, $tries = 0){ 
     if($tries >= 10){ 
      return false; 
     } 

     return fwrite($fp, $msg, strlen($msg)) ? self::sendSSLMessage($fp, $msg, $tries++) : true; 
    } 

我没有收到来自苹果的错误信息,一切只是没有人收到通知看起来不错。在这之前,我正在使用一种方法创建每个消息的一个套接字连接并在发送消息后关闭它,但它太慢了,所以我们决定更改它,所以我知道这不是客户端相关的问题。

回答

0

你必须首先箱$fp插座,然后将它传递给sendSSLMessage

// initally create Socket here 
$fp = self::createSocket(); 

foreach($devices as $device) { 
    $token = $device->getToken(); 
    $msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $token)) . pack('n', strlen($payload)) . $payload; 

    if(!self::sendSSLMessage($fp, $msg)){ 
     fclose($fp); 
     $fp = self::createSocket(); 
    } 
} 
fclose($fp); 

UPDATE

// define in $body['aps'] message with sub array like this 
$message = $notification->getMessage(); 
$body['aps'] = array(
      'alert' => array(
         'body' => $message, 
      ), 
      'sound' => 'default', 
); 
+0

哦对不起我忘了贴这一个了,但我只是在foreach以前做过循环。我将编辑该问题以添加此行。 – Supamiu

+0

好的,那么PUSH_IOS_CERTIFICAT_LOCATION'.pem'文件权限呢?重要的是它会有正确的权限尝试chmod它到0777 – Armen

+0

它的完成,我也看到没有SSL错误,因为如果我有一个SSL错误,它被添加到日志中(我删除了代码中的每个日志调用但有很多) – Supamiu