Android,快速将消息推送到1000台设备

Dan*_*iel 5 php android push-notification android-c2dm

我已经实现了c2dm,它可以正常工作,接收消息和一切.然而,有一个问题我无法找到解决方案.

当某个事件发生时,我想快速将相同的消息推送到几千个设备,最好是在一分钟内.我知道无法确定是否会传递此消息,并且Google可能会因不同情况而延迟发送消息.

我的iOS实现大致相同,当然发送部分除外.对于15000条消息,大约需要5秒.对于5000条到Android的消息,它需要一个多小时才能实现.

有谁知道加速这个的方法?或谷歌是否停止这种大规模推动以阻止垃圾邮件?

代码的C2DM部分如下.这是在PHP中,但我读大多数其他编程语言没有问题.我使用脚本连接()一次然后循环所有标记并使用sendMessage()发送每条消息.发送完所有消息后,它会断开连接().

<?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;
    }
}
?>
Run Code Online (Sandbox Code Playgroud)

编辑: 新的解决方案基于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);
    }
}
?>
Run Code Online (Sandbox Code Playgroud)

pet*_*ter 4

[更新] C2DM 现已弃用。它的后继者Google Cloud Messaging (GCM)支持多个接收器,也称为批量发送:

{ "data": {
  "score": "5x1",
  "time": "15:10"
  },
  "registration_ids": ["4", "8", "15", "16", "23", "42"]
}
Run Code Online (Sandbox Code Playgroud)

[/更新]

C2DM尚不支持批量发送。

然而,您可以同时向 C2DM 服务器发送多个 POST 请求,不幸的是 PHP 本身不支持多线程。

看一下curl_multi_exec,它提供了同时发出多个cURL 请求的可能性。