Created
June 3, 2012 01:58
-
-
Save mhlipson/2860954 to your computer and use it in GitHub Desktop.
Call C2DM in parallel using PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
class.C2DMParallel.php | |
PHP Class to send single messages to multiple devices | |
using Google's C2DM service. | |
*/ | |
class C2DMParallel{ | |
private $client = ''; //Client ID | |
private $secret = ''; // Client SECRET | |
private $refresh = ''; // Refresh Key | |
private $limit = 500; // The number of calls to process at once | |
private $access; | |
public function __construct(){ | |
$this->access = $this->update_auth(); | |
if(is_null($this->access)){ | |
die('Cannot update auth'); | |
} | |
} | |
/* | |
I'm putting this up top because it needs to be edited for your own purposes. | |
Google will return errors, you WILL need to handle them respectively | |
*/ | |
private function handle_responses($responses){ | |
foreach($responses as $registration_id => $response){ | |
// Split the response | |
$exp = explode('=',$response); | |
if($exp[0] == 'Error'){ | |
switch ($exp[1]) { | |
case 'QuotaExceeded': | |
// Don't send messages until next day | |
break; | |
case 'DeviceQuotaExceeded': | |
// Give uer a break | |
break; | |
case 'InvalidRegistration': | |
# Remove registration_id | |
break; | |
case 'NotRegistered': | |
# Remove registration_id | |
break; | |
case 'MessageTooBig': | |
# Stop process | |
break; | |
case 'MissingCollapseKey': | |
# Stop process | |
break; | |
default: | |
# code... | |
break; | |
} | |
} | |
print_r($exp); | |
} | |
} | |
public function execute( $message, $users = array() , $collapse_key = 1){ | |
$groups = array_chunk($users, $this->limit); | |
foreach($groups as $group){ | |
$tmp = $this->process_curl_parallel($group, $message,$collapse_key); | |
$this->handle_responses($tmp); | |
unset($tmp); | |
} | |
} | |
private function update_auth(){ | |
$url = "https://accounts.google.com/o/oauth2/token"; | |
$fields = array( | |
'grant_type' => 'refresh_token', | |
'client_id' => $this->client, | |
'client_secret' => $this->secret, | |
'refresh_token' => $this->refresh | |
); | |
$ch = curl_init(); | |
curl_setopt($ch,CURLOPT_URL,$url); | |
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
$output = curl_exec($ch); | |
$info = curl_getinfo($ch); | |
curl_close($ch); | |
$key = json_decode($output,TRUE); | |
if(!isset($key['access_token'])){ | |
return null; | |
} else { | |
return $key['access_token']; | |
} | |
} | |
/* | |
Performs the curl_multi call | |
*/ | |
private function process_curl_parallel($users,$data,$collapse_key){ | |
// Set Headers | |
$headers = array('Authorization: Bearer ' . $this->access); | |
// SET URL | |
$url = 'https://android.apis.google.com/c2dm/send'; | |
//$url = 'https://android.apis.google.com/c2dm/send'; | |
// Prepare Message | |
foreach($data as $key => $value){ | |
$message['data.' . $key] = $value; | |
} | |
// Init CURL MULTI | |
$mh = curl_multi_init(); | |
// Stage Individual Messages | |
$i = 0; | |
foreach($users as $key => $registration_id){ | |
// Complete staging for messages | |
$message['registration_id'] = $registration_id; | |
$message['collapse_key'] = $collapse_key; | |
// Init Curl | |
$ch[$registration_id] = curl_init(); | |
curl_setopt($ch[$registration_id], CURLOPT_URL, $url); | |
curl_setopt($ch[$registration_id], CURLOPT_HEADER, 0); | |
curl_setopt($ch[$registration_id], CURLOPT_POSTFIELDS, $message); | |
curl_setopt($ch[$registration_id], CURLOPT_HTTPHEADER, $headers); | |
curl_setopt($ch[$registration_id], CURLOPT_RETURNTRANSFER, TRUE); | |
curl_multi_add_handle($mh,$ch[$registration_id]); | |
$i++; | |
} | |
// Run the multi_curl | |
$responses = array(); | |
do { | |
$code = curl_multi_exec($mh,$still_executing); | |
if ($code==CURLM_OK) { | |
while ($done=curl_multi_info_read($mh)) { | |
$c = $done['handle']; | |
// Grab the Key from the handle | |
$key = array_search($done['handle'], $ch); | |
$responses[$key] = curl_multi_getcontent($c); | |
// Remove handles | |
curl_multi_remove_handle($mh,$c); | |
} | |
} elseif ($code!=CURLM_CALL_MULTI_PERFORM) { | |
throw new RuntimeException("multi_curl failure [$code]"); | |
} | |
} while ($still_executing); | |
curl_multi_close($mh); | |
return $responses; | |
} | |
} | |
/* | |
Usage | |
*/ | |
$c2dm = new C2DMParallel(); | |
/* | |
$users = array('device_key','device_key','device_key'); | |
*/ | |
$users = array(); | |
/* | |
Messages are associative arrays.. Remember they are limited to 1024 bytes. | |
$message = array( | |
'field' => 'body', | |
'field2' => 'body2' | |
); | |
*/ | |
$message = array('type' => 2); | |
$c2dm->execute($message,$users,4); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment