【问题标题】:Android, push messages to 1000 devices fastAndroid,将消息快速推送到 1000 台设备
【发布时间】:2012-01-09 14:08:26
【问题描述】:

我已经实现了 c2dm,并且设备可以正常接收消息和所有内容。 但是有一个问题我找不到解决方案。

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

除了发送部分,我的 iOS 实现大致相同。 15000 条消息大约需要 5 秒。向 Android 发送 5000 条消息需要一个多小时。

有人知道加快速度的方法吗? 还是 Google 会停止这种大规模推送以阻止垃圾邮件?

代码的 C2DM 部分如下。这是在 PHP 中,但我在阅读大多数其他编程语言时没有问题。 我使用脚本 connect() 一次,然后循环所有令牌并使用 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;
    }
}
?>

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

在循环通过数据库查询结果时收集卷曲句柄。在收集了几百个 curl 句柄之后,调用 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);
    }
}
?>

【问题讨论】:

    标签: php android push-notification android-c2dm


    【解决方案1】:

    [更新] C2DM 现在是 deprecated。它的继任者Google Cloud Messaging (GCM) 支持multiple receivers 又名批量发送:

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

    [/更新]

    C2DMdoesn't support批量发送尚未。

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

    查看curl_multi_exec,它可以同时发出多个 cURL 请求。

    【讨论】:

    • 我知道 C2DM 不支持批量发送,因此我为每条消息创建一个 POST。由于某种原因,这个过程需要很长时间。我将看看 curl_multi_exec。也许是 curl 本身需要很多时间。如果我发现一些有趣的东西,我会多花点时间回来。
    • curl_multi_exec 似乎是解决方案。经过几天的测试,发送 5000 条消息的时间从一个多小时缩短到几秒钟。但是,如果消息曾经收到消息,这是非常随机的。有些人似乎在路上迷路了。我想一次 2000 条消息太多了,我会尝试调整它以获得最佳性能与速度。有时间我会更新原帖的。
    【解决方案2】:

    我还会调查 Firebase,我最近一直在和他们一起玩,而且看起来真的很快。他们有适用于相当广泛的框架的 API。他们的目标是非常快速地将更改推送到数据集(消息就是一个很好的例子),因此当发生更改时,他们会向所有连接的用户发送通知消息。

    https://www.firebase.com/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-25
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      相关资源
      最近更新 更多