私はc2dmを実装しており、デバイスがメッセージとすべてを受信するようにうまく動作します。 解決策が見つからないという問題が1つあります。Android、1000個のデバイスに高速にメッセージを送信
特定のイベントが発生した場合、同じメッセージを数千のデバイスに素早く、できれば1分以内にプッシュしたいと考えています。メッセージが配信されることは確実ではなく、状況によってはGoogleがメッセージを遅らせる可能性があることはわかっています。
iOSの実装は、送信部を除いてほぼ同じです。それは15000メッセージに対して約5秒かかります。 Androidへの5000件のメッセージには1時間以上かかりますが、これは長いです。
誰かがこれをスピードアップする方法を知っていますか? Googleはこのような大量攻撃を阻止してスパムを阻止していますか?
コードのC2DM部分は次のとおりです。これはPHPで書かれていますが、他のほとんどのプログラミング言語を読んでも問題はありません。 私はconnect()を一回実行した後にすべてのトークンをループし、sendMessage()を使って各メッセージを送信するスクリプトを使用します。すべてのメッセージが送信されると、disconnect()が呼び出されます。
<?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;
}
}
?>
EDIT: 新しいソリューションをcurl_multi_execに基づいています。
データベースクエリー結果をループしながら、カールハンドルが収集されます。数百のカールハンドルが集められた後、sendMessages($ chs)が呼び出されてこれらのメッセージがすべて送信されます。現時点では、私は700メッセージを送信する前に収集し、良い配信速度と十分に速いと思われる、〜10秒5000メッセージを送信します。数値が高いほど配信レートに影響するようです。
<?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);
}
}
?>
私はC2DMは、バッチ送信し、そのための私はメッセージごとに1つのPOSTを行うことをサポートしていないことを知っています。何らかの理由でこのプロセスには本当に時間がかかります。私はcurl_multi_execを見ていきます。たぶんそれは多くの時間を取るカールそのものです。私はもう少し時間があり、何か興味深いものが見つかると戻ってきます。 – Daniel
curl_multi_execが解決策に見えました。数日間テストした後、5000メッセージを送信する時間は1時間以上から数秒になりました。しかし、メッセージがメッセージを受け取る場合はかなりランダムです。途中で失われそうな人もいます。私は一度に2000のメッセージがたくさんあると思うし、最適なパフォーマンスとスピードのためにこれを微調整しようとします。私は時間が来たら元の投稿を更新します。 – Daniel