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

Ой извините я забыл вставить этот тоже, но я сделал это как раз перед Еогеасп петля. Я отредактирую вопрос, чтобы добавить эту строку. – Supamiu

+0

Хорошо, а как насчет разрешения файла PUSH_IOS_CERTIFICAT_LOCATION '.pem'? важно, чтобы у него было правильное разрешение, попробуйте chmod его до 0777 – Armen

+0

, это сделано, также я увидел, что нет ошибки SSL, потому что, если у меня есть ошибка SSL, она добавляется в журналы (я удалял каждый вызов журнала в коде но их много) – Supamiu

Смежные вопросы