Skip to content

Instantly share code, notes, and snippets.

@razarahil
Forked from mhlipson/class.C2DMParallel.php
Created June 3, 2012 20:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save razarahil/2864921 to your computer and use it in GitHub Desktop.
Save razarahil/2864921 to your computer and use it in GitHub Desktop.
Call C2DM in parallel using PHP
<?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