2

I know this question has been asked several times but I'm looking for another answer to my problem.

Basically, I have a MYSQL database with over 10000 records of iPhone's device ID for push notifications in it.

Now, I need to run a PHP file that will connect to the Apple APNS server to send push notification to these 10000 records in my MYSQL database.

When I run my php page, after a while i get a timed out error...

in my research I came across a few solutions BUT most require to edit some stuff in etc folder on the server.

My question is:

is there any way to select lets say 30 records from MYSQL database, then stop and then select another 30 and then stop and then another 30 and so on and so forth until the who records have been sent the PN's?

This is my current code:

$message = "Welcome";

$sqld = "SELECT * FROM pushUsers ORDER BY id DESC";
$queryd = mysqli_query($db_conx, $sqld);
$productCountd = mysqli_num_rows($queryd); // count the output amount
if ($productCountd > 0) {
    //while($rowd = mysqli_fetch_array($queryd, MYSQLI_ASSOC)){ 
        while($rowd = mysqli_fetch_assoc($queryd)){ 
             $deviceID = $rowd["deviceNo"];
             $deviceType = $rowd["deviceType"];

             if($deviceType == 'iPhone' || $deviceType == 'iPad'){

 ///////////////SEND PUSH NOTU8FOCATION FOR iOS//////////////////////

              // Put your device token here (without spaces):

   $deviceToken = ''. $deviceID.'';


    // Put your private key's passphrase here:
    $passphrase = '123456';

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

    $ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'local_cert', 'apple_push_notification_production.pem');
    stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

    // Open a connection to the APNS server
    //****IMPORTANT**** LIVE APNS URL: 

    //ssl://gateway.sandbox.push.apple.com:2195


    $fp = stream_socket_client(
      'ssl://gateway.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;

    // Create the payload body
    $body['aps'] = array(
        'alert' => ''.$message.'',
        'sound' => 'default',
        'link_url' => 'http://xxxx.xom',
        'category' => 'APP',
        'badge'  => '1',
    );

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

    // Send it to the server
    $result = fwrite($fp, $msg, strlen($msg));

    if (!$result)
      echo 'Message not delivered' . PHP_EOL;
    else
      echo 'Message successfully delivered' . PHP_EOL;

    // Close the connection to the server
    fclose($fp);

    ///////////////END SEND PUSH NOTU8FOCATION FOR iOS//////////////////////

}


    }
} else {
}

ANY HELP WOULD BE APPRECIATED.

Thanks in advance.

David Hope
  • 1,426
  • 4
  • 21
  • 50
  • Possible duplicate of [Pagination using MySQL LIMIT, OFFSET](https://stackoverflow.com/questions/20364349/pagination-using-mysql-limit-offset) – bishop Sep 04 '17 at 16:54
  • you can store current database position in a file – vadim_hr Sep 04 '17 at 16:54
  • 1
    @bishop, pagination?!? – David Hope Sep 04 '17 at 17:05
  • "select lets say 30 records from MYSQL database, then stop and then select another 30 and then stop and then another 30 and so on": that is the same pattern as pagination. – bishop Sep 04 '17 at 17:12
  • @bishop, no it is not. Pagination does NOT stop... It will grab all the records at once but it will break the records down into bulks of 10, 20, 30 etc... – user2056633 Sep 04 '17 at 17:30
  • Not pagination by itself, @user2056633: `SELECT .. LIMIT .. OFFSET`, do work, sleep possibly with exponential back off, increment offset, repeat. I don't see how this algorithm diverges from the desired class of solutions and the "hardest" part about it pagination. – bishop Sep 04 '17 at 17:34
  • @bishop, your choice of word and example "pagination" is wrong in this instance. You could be right about the select... Limit...offset... – user2056633 Sep 04 '17 at 17:37
  • See also http://mysql.rjweb.org/doc.php/pagination – bishop Sep 04 '17 at 17:41

2 Answers2

1

There are a few ways to solve your problem.

I can't help you writing code, instead I'll write some conceptual tips.

Change maximum execution time in PHP

Use set_time_limit() to increase execution time limit.

But, if your PHP is running in safe_mode, this function has no effect.

Split your job

The way to do it depends on how you call this PHP file, if it's a cron job, you can persist the last index that you pushed the notification, then call the cron job multiple times.

Improve the performance

The push service should have a bulk method, where you send many notifications in a single http request. The HTTP request is the bottleneck here, not the database.

Every request have it own delay, if you have 10k rows in database, there will be 10k requests. If the request takes 10ms (a very low time), you will take 100 seconds to execute your script.

If you send your notifications in a bulk method that accepts 100 notifications per request and take 50ms to run, you will need only 100 requests, and will take only 5 seconds to execute it.

Doing this way, you can split your mysql query with LIMIT and OFFSET, so you only load in the memory what you need before sending the request.

Elias Soares
  • 9,884
  • 4
  • 29
  • 59
0

Yes, you need to send push notification in 100-100 or 500-500 at once because may be your server not too much strong for 10,000 record process at once and other reason is that may be your execution time is 30 sec or something like that so a script run for particular time and after that its give timeout.

$message = "Welcome";
for($i=10000 ;$i>0;$i-$limit){
//your code here
sleep(2);
}
Priyanka Sankhala
  • 808
  • 1
  • 9
  • 25