2015-12-22 187 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