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

     2023-02-24     131

关键词:

【中文标题】Android,将消息快速推送到 1000 台设备【英文标题】:Android, push messages to 1000 devices fast 【发布时间】: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);
    

?>

【问题讨论】:

【参考方案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/

【讨论】:

如何在没有安装 MQTT 应用程序的设备的情况下在 android 上使用 MQTT 将消息推送到特定 IP?

】如何在没有安装MQTT应用程序的设备的情况下在android上使用MQTT将消息推送到特定IP?【英文标题】:HowtouseMQTTonandroidtopushmessagestoaspecificIPwithoutthedevicehavingtheMQTTappinstalled?【发布时间】:2017-07-2916:57:36【问题描述】:我在JavaAndroi... 查看详情

如何在本机反应中将设备的通知推送到另一台设备

】如何在本机反应中将设备的通知推送到另一台设备【英文标题】:Howtopushnotificationbyadevicetoanotherdeviceinreactnative【发布时间】:2020-03-0820:21:52【问题描述】:谁能告诉我如何将一个设备的通知推送到另一个设备?如果它在OneSigna... 查看详情

无法将通知推送到 iOS9 设备

...:47【问题描述】:每当我尝试使用PushforiOS8Bluemix仪表板将消息推送到已注册的设备时,都会出现一条消息“通知已发送”。显示,但我的注册设备从未收到通知。根据我的应用程序的日志,设备似乎已正确注册到PushforiOS8服务,... 查看详情

AWS SNS 发布的消息未推送到设备

...描述】:我正在尝试使用AWSSNS来替代运行我自己的向iOS和Android应用程序发送推送通知的服务。我从GCM开始,所以我在SNS中创建了一个GCM应用程序,然后添加了一个端点。当我从AWS控制台发布消息时,它可以很好地传递到设备,... 查看详情

无需谷歌云消息(GCM)将通知从 PC 推送到 android

】无需谷歌云消息(GCM)将通知从PC推送到android【英文标题】:PushnotificationfromPCtoandroidwithoutGooglecloudmessaging(GCM)【发布时间】:2014-07-0907:35:23【问题描述】:无需Google云消息(GCM)即可将通知从PC推送到android我想创建关闭通知服务... 查看详情

使用 AWS-Pinpoint 将通知推送到多个设备

...发送通知,并且工作正常。通过使用SendMessages,我可以将消息发送到多个端点。"ApplicationId":"adknja 查看详情

无法将 Azure NotificationHub 推送消息从 .NET 控制台应用程序传送到(Android)设备

...将AzureNotificationHub推送消息从.NET控制台应用程序传送到(Android)设备【英文标题】:FailingtodeliverAzureNotificationHubpushmessagesto(Android)devicesfrom.NETconsoleapp【发布时间】:2016-03-0919:36:19【问题描述】:我已使用较新的Azure门户中的“快... 查看详情

将通知从 python 推送到 android

】将通知从python推送到android【英文标题】:Pushnotificationfrompythontoandroid【发布时间】:2018-04-1713:52:32【问题描述】:我正在运行一些脚本,并在脚本运行完成后寻找一种简单的方法来ping我的手机。在网络上做一些研究,我看到... 查看详情

将数据推送到设备的最佳方式是啥? [关闭]

...】:2012-01-1021:50:53【问题描述】:我正在制作一个需要与Android手机通信的网络应用程序,从网络应用程序获取数据到手机的最佳方式是什么?我听说过C2DM,但我不知道有什么好的指南。我试过轮询,但这对电池来说太重了。实... 查看详情

GCM 推送通知,其中消息从移动设备推送到 GCM 服务器

】GCM推送通知,其中消息从移动设备推送到GCM服务器【英文标题】:GCMPushNotificationwherebyMessageisPushFromMobileToGCMServer【发布时间】:2014-08-0604:21:16【问题描述】:你们中的任何一个都可以提供GCM推送通知的代码,其中消息从移动设... 查看详情

要从 MobileFirst 服务器推送到移动设备的加密推送通知消息

】要从MobileFirst服务器推送到移动设备的加密推送通知消息【英文标题】:encryptedpushnotificationmessagestobepushedfromMobileFirstservertomobile【发布时间】:2016-06-2805:00:03【问题描述】:我们正在使用MobileFirstV7.1开发一个BankingMobile应用程序... 查看详情

是否有 API 可以一次性将不同的通知推送到一百万台设备?

...ushy、Parse等,所有这些都可以向一百万台设备广播相同的消息。Azure、OneSigna 查看详情

单推接收,但推送到多个设备,不接收

】单推接收,但推送到多个设备,不接收【英文标题】:singlepushreceives,butpushtomultipledevice,don\'treceive【发布时间】:2015-08-2701:14:08【问题描述】:我的数据库中注册了16台设备。当我推送到单个设备时,它发送和接收成功,但是... 查看详情

Gcp PubSub 未将消息推送到 REST 端点

】GcpPubSub未将消息推送到REST端点【英文标题】:GcpPubSubnotpushingmessagetoRESTEndpoint【发布时间】:2017-07-1717:38:32【问题描述】:我遇到了一个问题,GcpPubSub没有将消息推送到我注册的端点。让我详细叙述一下我执行的步骤。注意,... 查看详情

快速将 UIImage 推送到下一个视图控制器

】快速将UIImage推送到下一个视图控制器【英文标题】:PushingUIImagetonextviewcontrollerinswift【发布时间】:2018-04-2315:20:45【问题描述】:我已成功将图像解析为cellForRowAt,但现在需要为didSelectRowAt显示ResultsViewController中的食谱,但遇... 查看详情

使用 AFNetworking 将 Firebase 通知从 ios 设备推送到花药

】使用AFNetworking将Firebase通知从ios设备推送到花药【英文标题】:pushfirebasenotificationfromiosdevicetoantherusingAFNetworking【发布时间】:2018-09-2515:37:52【问题描述】:我从云数据库(firebase服务器)推送通知,但我想如何使用AFNetworking将... 查看详情

如何将消息从 Activemq 推送到消费者

】如何将消息从Activemq推送到消费者【英文标题】:HowtopushmessagesfromActivemqtoconsumer【发布时间】:2013-09-0822:52:39【问题描述】:我是Activemq和Java的新手,看了教程,有点懂了。谁能帮我解决以下任务。假设我们在Activemq的Queue/Topic... 查看详情

Spring boot:将消息推送到每个请求的特定主题

】Springboot:将消息推送到每个请求的特定主题【英文标题】:Springboot:pushmessagetospecifictopicforeachrequest【发布时间】:2020-04-0123:55:02【问题描述】:我正在使用pubsub与springboot的集成,我的配置类如下所示:@ConfigurationpublicclassPubSub... 查看详情