C2dm'yi uyguladım ve cihazın mesajı ve her şeyi alması gayet iyi çalışıyor. Ancak, bir çözüm bulamadığım bir sorun var.Android, mesajları hızlı bir şekilde 1000 cihaza aktarır.
Belirli bir olay meydana geldiğinde, aynı mesajı birkaç bin cihaza hızla, tercihen bir dakika içinde itmek istiyorum. Mesajın teslim edileceğine dair bir kesinlik olmadığını ve Google'ın farklı durumlar nedeniyle iletiyi geciktirebileceğini biliyorum.
iOS için uygulamam, gönderen kısım haricinde aynıdır. Bu 15000 mesaj için yaklaşık 5 sn sürüyor. Android'e 5000 mesaj için, bir saatten uzun sürüyor.
Bunu hızlandırmak için bir yol bilen var mı? Veya Google bu tür kitle iletilerini spam'i durdurmak için durdurur mu?
Kodun C2DM kısmı aşağıdadır. Bu PHP'de ama diğer programlama dillerinin çoğunu okumada sorun yaşıyorum. Bir kerede connect() için bir komut dosyası kullanıyorum ve sonra tüm tokenleri döngü yapıyorum ve her bir mesajı göndermek için sendMessage() öğesini kullanın. Tüm mesajlar gönderildikten sonra,() bağlantısını kesin.
<?php
class C2DMclient
{
private $authKey = NULL;
private $ch = NULL;
function connect() {
$post_params = array(
'Email' => 'C2DM_USER',
'Passwd' => 'C2DM_PWD',
'accountType' => 'HOSTED_OR_GOOGLE',
'source' => 'appname',
'service' => 'ac2dm',
);
$first = true;
$data_msg = '';
foreach($post_params as $key => $value) {
if($first)
$first = false;
else
$data_msg .= '&';
$data_msg .= urlencode($key).'='.urlencode($value);
}
$x = curl_init('C2DM_CLIENTLOGIN');
curl_setopt($x, CURLOPT_HEADER, true);
curl_setopt($x, CURLOPT_POST, true);
curl_setopt($x, CURLOPT_POSTFIELDS, $data_msg);
curl_setopt($x, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($x);
curl_close($x);
$pos = strpos($response, 'Auth=');
$this->authKey = trim(substr($response, 5 + $pos));
$this->ch = curl_init();
curl_setopt($this->ch, CURLOPT_URL, 'C2DM_SERVER');
}
function disconnect() {
curl_close($this->ch);
$this->authKey = NULL;
}
function sendMessage($deviceToken, $message) {
$data = array(
'registration_id' => $deviceToken,
'collapse_key' => 'ck_type',
'data.type' => 'TYPE',
'data.message' => $message,
'data.title' => 'Title'
);
$headers = array('Authorization: GoogleLogin auth='.$this->authKey);
if($headers)
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($this->ch, CURLOPT_POST, true);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
$messagedata = curl_exec($this->ch);
return TRUE;
}
}
?>
DÜZENLEME: Yeni çözüm curl_multi_exec dayanmaktadır.
Veritabanı sorgusu sonuçlarında döngü yaparken kıvrılmış tutamaçlar toplanır. Birkaç yüz kıvrık tutamaç toplandıktan sonra, tüm bu mesajları göndermek için sendMessages ($ chs) çağrılır. Şu anda göndermeden önce 700 mesaj topladım ve iyi bir dağıtım oranına ve yeterince hızlı var gibi görünüyor, ~ 10s 5000 mesaj göndermek için. Daha yüksek bir sayı, yayınlanma oranını etkiler.
<?php
class C2DMclient
{
private $authKey = NULL;
private $ch = NULL;
function connect() {
$post_params = array(
'Email' => 'C2DM_USER',
'Passwd' => 'C2DM_PWD',
'accountType' => 'HOSTED_OR_GOOGLE',
'source' => 'appname',
'service' => 'ac2dm',
);
$first = true;
$data_msg = '';
foreach($post_params as $key => $value) {
if($first)
$first = false;
else
$data_msg .= '&';
$data_msg .= urlencode($key).'='.urlencode($value);
}
$x = curl_init('C2DM_CLIENTLOGIN');
curl_setopt($x, CURLOPT_HEADER, true);
curl_setopt($x, CURLOPT_POST, true);
curl_setopt($x, CURLOPT_POSTFIELDS, $data_msg);
curl_setopt($x, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($x);
curl_close($x);
$pos = strpos($response, 'Auth=');
$this->authKey = trim(substr($response, 5 + $pos));
}
function getMessageCurlHandle($deviceToken, $message) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'C2DM_SERVER');
$data = array(
'registration_id' => $deviceToken,
'collapse_key' => 'ck_type',
'data.type' => 'TYPE',
'data.message' => $message,
'data.title' => 'Title'
);
$headers = array('Authorization: GoogleLogin auth='.$this->authKey);
if($headers)
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
return $ch;
}
function sendMessages($chs) {
$mh = curl_multi_init();
foreach($chs as $ch) {
curl_multi_add_handle($mh, $ch);
}
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while($mrc == CURLM_CALL_MULTI_PERFORM);
while($active && $mrc == CURLM_OK) {
if(curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
curl_multi_close($mh);
}
}
?>
Ben C2DM toplu gönderme desteklemediğini biliyorum ve bunun ben her mesaj için bir POST olun. Bazı sebeplerden dolayı bu süreç çok uzun zaman alıyor. Curl_multi_exec'e bir göz atacağım. Belki de çok zaman alan kendini kıstırır. İlginç bir şey bulursam biraz daha zaman kazanırım. – Daniel
curl_multi_exec çözüm gibi görünüyordu. Birkaç gün boyunca test ettikten sonra 5000 mesaj gönderme zamanı bir saatten fazla bir süreye geçti. Ancak mesajın mesajları alması oldukça rastlantısaldır. Bazıları yolda kaybolmuş gibi görünüyor. Bir kerede 2000 mesajın çok olduğu sanırım ve bu hıza göre en iyi performans için bunu düzeltmeye çalışacağım. Zamanı aldığımda asıl gönderiyi güncelleyeceğim. – Daniel