Android的推送消息到1000设备快速消息、快速、设备、Android

2023-09-05 01:01:52 作者:蜜餹

我已经实现C2DM并能正常工作,该设备接收消息和一切。 然而,有,我不能找到一个解决方案的一个问题。

当某个事件发生时我想一分钟内pferably推同样的消息到几千元的设备迅速,$ P $。我知道,目前还不能确定这条消息将不断交付,而谷歌可能会延迟邮件由于不同的情况。

我的实现为iOS是关于发送部分,当然​​,除了相同的。这大约需要5秒,15000的消息。对于5000的消息到Android花费了一个多小时,这是路长。

有谁知道一种方法,以加快这件事? 还是谷歌停止这种大规模推来阻止垃圾邮件?

的code的C2DM部分如下。这是PHP的,但我没有问题,阅读其他大多数编程语言。 我用一个脚本连接()一次,然后循环中的所有标记和使用的sendMessage()发送每封邮件。之后所有的消息发出后,它断开()。

 < PHP
类C2DMclient
{
    私人$ authKey = NULL;
    私人$ CH = NULL;

    功能连接(){
        $ post_params =阵列(
            电子邮件=> C2DM_USER,
            '的passwd'=> C2DM_PWD,
            accountType'=> HOSTED_OR_GOOGLE,
            '源'=> 应用程序名称,
            '服务'=> ac2dm,
        );
        $第一= TRUE;
        $ data_msg ='';

        的foreach($ post_params作为$关键=> $值){
            如果($第一)
                $第一= FALSE;
            其他
                $ data_msg ='和;。

            $ data_msg = urlen code($键)'='urlen code($值)。;
        }

        $ X = curl_init('C2DM_CLIENTLOGIN');
        curl_setopt($ X,CURLOPT_HEADER,真正的);
        curl_setopt($ X,CURLOPT_POST,真正的);
        curl_setopt($ X,CURLOPT_POSTFIELDS,$ data_msg);
        curl_setopt($ X,CURLOPT_RETURNTRANSFER,真正的);
        $响应= curl_exec($ X);
        curl_close($ X);

        $ POS = strpos($响应,'验证=');
        $这个 - > authKey =修剪(SUBSTR($响应,5 + $ POS));
        $这 - > CH = curl_init();
        curl_setopt($这 - >沟道,CURLOPT_URL,'C2DM_SERVER');
    }

    功能断开(){
        curl_close($这个 - > CH);
        $这个 - > authKey = NULL;
    }

    SendMessage函数($ deviceToken,$消息){
        $数据=阵列(
            registration_id'=> $ deviceToken,
            collapse_key'=> ck_type,
            data.type'=> '类型',
            data.message'=> $消息,
            data.title'=> '标题'
        );
        $标题=阵列(授权:的GoogleLogin权威性='$这个 - > authKey。);

        如果($头)
            curl_setopt($这个 - > CH,CURLOPT_HTTPHEADER,$头);

        curl_setopt($这 - >沟道,CURLOPT_SSL_VERIFYPEER,0);
        curl_setopt($这个 - > CH,CURLOPT_POST,真正的);
        curl_setopt($这个 - > CH,CURLOPT_RETURNTRANSFER,真正的);
        curl_setopt($这个 - > CH,CURLOPT_POSTFIELDS,$数据);

        $ messagedata = curl_exec($这个 - > CH);
            返回TRUE;
    }
}
?>
 

编辑: 新的解决方案是基于curl_multi_exec。

同时,通过数据库查询结果的循环

卷曲手柄被收集。经过几百卷曲手柄云集,sendMessages($ CHS)被称为发送所有这些信息。目前,我收700的邮件发送之前,似乎有一个良好的交货速度和足够快,〜10秒发送5000条消息。数字越大,似乎影响分娩率。

 < PHP
类C2DMclient
{
    私人$ authKey = NULL;
    私人$ CH = NULL;

    功能连接(){
        $ post_params =阵列(
            电子邮件=> C2DM_USER,
            '的passwd'=> C2DM_PWD,
            accountType'=> HOSTED_OR_GOOGLE,
            '源'=> 应用程序名称,
            '服务'=> ac2dm,
        );
        $第一= TRUE;
        $ data_msg ='';

        的foreach($ post_params作为$关键=> $值){
            如果($第一)
                $第一= FALSE;
            其他
                $ data_msg ='和;。

            $ data_msg = urlen code($键)'='urlen code($值)。;
        }

        $ X = curl_init('C2DM_CLIENTLOGIN');
        curl_setopt($ X,CURLOPT_HEADER,真正的);
        curl_setopt($ X,CURLOPT_POST,真正的);
        curl_setopt($ X,CURLOPT_POSTFIELDS,$ data_msg);
        curl_setopt($ X,CURLOPT_RETURNTRANSFER,真正的);
        $响应= curl_exec($ X);
        curl_close($ X);

        $ POS = strpos($响应,'验证=');
        $这个 - > authKey =修剪(SUBSTR($响应,5 + $ POS));
    }

    功能getMessageCurlHandle($ deviceToken,$消息){
        $ CH = curl_init();
        curl_setopt($沟道,CURLOPT_URL,'C2DM_SERVER');
        $数据=阵列(
            registration_id'=> $ deviceToken,
            collapse_key'=> ck_type,
            data.type'=> '类型',
            data.message'=> $消息,
            data.title'=> '标题'
        );
        $标题=阵列(授权:的GoogleLogin权威性='$这个 - > authKey。);

        如果($头)
            curl_setopt($ CH,CURLOPT_HTTPHEADER,$头);
        curl_setopt($沟道,CURLOPT_SSL_VERIFYPEER,0);
        curl_setopt($ CH,CURLOPT_POST,真正的);
        curl_setopt($ CH,CURLOPT_POSTFIELDS,$数据);
        返回$ CH;
    }

    功能sendMessages($ CHS){
        $ MH = curl_multi_init();
        的foreach($ CHS为$ CH){
            curl_multi_add_handle($ MH,$ CH);
        }
        $积极= NULL;
        做 {
            $ MRC = curl_multi_exec($ MH,$活动);
        }而($ MRC == CURLM_CALL_MULTI_PERFORM);

        而($活跃和放大器;&安培; $ MRC == CURLM_OK){
            如果(curl_multi_select($ MH)!=  -  1){
                做 {
                    $ MRC = curl_multi_exec($ MH,$活动);
                }而($ MRC == CURLM_CALL_MULTI_PERFORM);
            }
        }
        curl_multi_close($ MH);
    }
}
?>
 
G18用什么版本的手机qq

解决方案

[更新] C2DM是现在的德precated 。它的继任者谷歌云消息(GCM)支持的多个接收器的又名批量发送:

  {数据:{
  分数:5X1
  时间:15:10
  },
  registration_ids:[4,8,15,16,23,42]
}
 

[/更新]

C2DM 不支持批量发送呢。

不过,你可以在同一时间发送多个POST请求C2DM服务器, 不幸的是PHP本身已经对多线程的支持。

看一看 curl_multi_exec 这给方法可行使几个卷曲请求同时

I have implemented c2dm and it works fine that the device receives the message and everything. There is however one problem that I can't find a solution for.

When a certain event occurs I want to push the same message to a few thousand devices quickly, preferably within a minute. I know that there is no certainty that the message will ever be delivered and that Google may delay the message due to different circumstances.

My implementation for iOS is about the same except of course the sending part. That takes about 5 sec for 15000 messages. For 5000 messages to Android it takes over an hour which is way to long.

Does anyone know a way to speed this up? Or does Google stop this kind of mass push to stop spam?

The C2DM part of the code is below. This is in PHP but I have no problem reading most other programming languages. I use a script to connect() once and then loop all tokens and use sendMessage() to send each message. After all messages is sent, it 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: New solution is based on curl_multi_exec.

Curl handles are collected while looping through the database query results. After a few hundred curl handles are gathered, sendMessages($chs) are called to send all those messages. At the moment I collect 700 messages before sending and seems to have a good delivery rate and fast enough, ~10s to send 5000 messages. A higher number seem to affect delivery rate.

<?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);
    }
}
?>

解决方案

[Update] C2DM is now deprecated. It's successor Google Cloud Messaging (GCM) supports multiple receivers aka batch sending:

{ "data": {
  "score": "5x1",
  "time": "15:10"
  },
  "registration_ids": ["4", "8", "15", "16", "23", "42"]
}

[/Update]

C2DM doesn't support batch sending yet.

However you could send several POST request to the C2DM server at the same time, unfortunately PHP has itself no support for multi-threading.

Have a look at curl_multi_exec which gives the possiblity to make several cURL requests at the same time.