首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用SNS主题向特定成员发送推送?

如何使用SNS主题向特定成员发送推送?
EN

Stack Overflow用户
提问于 2017-06-26 04:54:12
回答 2查看 1.2K关注 0票数 1

我正在使用AWS发送推送通知,现在我使用publish方法的aws-php-sdk发送推送特定的设备。--我的要求在30秒内被发送给成千上万的成员,。当我使用发布方法时,发送1000个用户需要5分钟。我读过关于topic的文章,它同时发送多个成员,但是我的场景是我想要发送推送给特定的用户,而不是所有的主题用户。

例如,我在一个主题中注册了10,000名成员,但从这10,000名成员中我发送了9,000名成员,有时是1000名成员。

因此,任何人都知道如何使用主题发送推送,但只有特定的成员。

我还想到了另一种情况,每次我创建新主题并为这个主题注册成员,然后向他发送一条消息,然后删除topic,但是这里每次注册成员也需要时间。所以,如果你有一个想法,一次注册多个成员,那么它也将对我有帮助。

下面是我当前发送推送的代码。

代码语言:javascript
复制
    $arn = "user arn";
    $sns = new Aws\Sns\SnsClient(array(
                    'version' => 'latest',
                    'key' => my_aws_key,
                    'secret' => aws_secret,
                    'region' => region,
                    'profile' => profile_name,
                    'debug' => false,
                    'http' => array('verify' => false)
                ));
$appArn = "application arn";

$sns->publish(array('Message' => '{ "GCM": "{\"data\": { \"message\": \" This is my message \"} }"}',
                     'MessageStructure' => 'json',
                     'TargetArn' => $arn
                        ));
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-03 10:54:16

在尝试了许多解决方案之后,我能够在一分钟内发送数千个通知,这里我展示了我是如何做到的,我已经完成了php multicurl功能,所以我执行多个并行进程,同时执行所有进程发送通知。

定义多个卷曲并准备发送通知

假设我有5,000个成员,并且我拥有它的令牌数组和其他成员详细信息-- $device_type_ids_arr i--所有成员的一部分--到500个组,那么每次curl执行时,它都会向500个成员发送通知

代码语言:javascript
复制
$_datas = array_chunk($device_type_ids_arr, 500);
/*initialise multi curl*/
$mh = curl_multi_init();
$handles = array();
/* Perform loop for each 500 members batch */
foreach ($_datas as $batchPart) {
    $ch = curl_init();
    $postData['devices'] = $batchPart;
    $postData['push_content'] = $push_content;
    $data_string = json_encode($postData);
    curl_setopt($ch, CURLOPT_URL, base_url() . "EmailPipe/sendNotification/"); //your URL to call amazon service (Explain below)
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_USERAGENT, 'User-Agent: curl/7.39.0');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length:' . strlen($data_string))
    );
    curl_multi_add_handle($mh, $ch);
    $handles[] = $ch;
}
// execute requests and poll periodically until all have completed
$isRunning = null;
do {
    curl_multi_exec($mh, $isRunning);
} while ($isRunning > 0);

/* Once all execution are complete remove curl handler */
foreach ($handles as $ch) {
    curl_multi_remove_handle($mh, $ch);
}
/* Close multi curl */
curl_multi_close($mh);

接收curl 请求并发送通知函数。

代码语言:javascript
复制
function sendCurlSignal() {
    require_once APPPATH . 'libraries/aws-sdk/aws-autoloader.php';
    $pipeArr = json_decode(file_get_contents('php://input'), true);
    $push_content = $pipeArr["push_content"];
    $device_id_arr = $pipeArr["devices"];
    $sns = new Aws\Sns\SnsClient(array(
        'version' => 'latest',
        'key' => "Amazon key",
        'secret' => "Amazon secret",
        'region' => "region like eu-west-1",
        'profile' => "Amazon account user",
        'debug' => false,
        'http' => array('verify' => false)
    ));
    $appArn = "SNS application arn";
    $promises = $results = $retArr = array();

    foreach ($device_id_arr as $key => $device_detail) {
        $arn = $device_detail['arn']; /* SNS ARN of each device */
        $token = $device_detail['token_id']; /* Registered token */
        $userid = $device_detail['member_id'];
        /* If you don't have arn then add arn for specific token in amazon */
        if (empty($arn)) {
            try {
                $updatedArn = $sns->createPlatformEndpoint(array('PlatformApplicationArn' => $appArn, 'Token' => $token));
                $arn = $newArn = isset($updatedArn['EndpointArn']) ? $updatedArn['EndpointArn'] : "";
                //update member detail with new arn
                if ($newArn != "" && $userid != "" && $token != "") {
                    /* You can update arn into database for this member */
                }
            } catch (Exception $e) {
                /* Get error if any */
                $errorMsg = $e->getMessage();
                $newFile = fopen("error_arn_fail.txt", "a+");
                fwrite($newFile, "Member Id:" . $userid . "\r\nToken:" . $token . "\r\n" . $errorMsg . "\r\n");
                fclose($newFile);
            }
        }
        if (!empty($arn)) {
            try {
                $promises[$userid] = $sns->publishAsync(array(
                    'Message' => '{ "GCM": "{\"data\": { \"message\": \"' . $push_content . '\" } }"}',
                    'MessageStructure' => 'json',
                    'TargetArn' => $arn
                ));
                $promises[$userid]->arn = $arn;
                $promises[$userid]->token = $token;
            } catch (Exception $e) {
                $errorMsg = $e->getMessage();
                $newFile = fopen("error_async_fail_signal.txt", "a+");
                fwrite($newFile, $errorMsg . "\r\n");
                fclose($newFile);
            }
        }
    }
    /* Broadcast push notification */
    $results = \GuzzleHttp\Promise\settle($promises)->wait(TRUE);

    /* if you want to get result of broadcast and sent message id then do following */
    foreach ($results as $key => $value) {
        if (isset($value['reason'])) {
            /* Reason come in case of fail */
            $message = $value['reason']->getMessage();
            $token = (isset($promises[$key]->token)) ? $promises[$key]->token : "";
            $arn = (isset($promises[$key]->arn)) ? $promises[$key]->arn : "";
            if (empty($arn) || empty($token) || empty($key)) {
                $newFile = fopen("error_empty_detail_result.txt", "a+");
                fwrite($newFile, "Member Id:" . $key . "\r\nArn:" . $arn . "\r\nToken:" . $token . "\r\n");
                fclose($newFile);
            }
            /* Handle error */
            if (strpos($message, "Endpoint is disabled") !== false && $token != "" && $arn != "") {
                try {
                    $res = $sns->setEndpointAttributes(array(
                        'Attributes' => array("Token" => $token, "Enabled" => "true"),
                        'EndpointArn' => $arn
                    ));
                } catch (Exception $e) {
                    $errorMsg = $e->getMessage();
                    $newFile = fopen("error_endpoint_disable.txt", "a+");
                    fwrite($newFile, "Member Id:" . $key . "\r\nArn:" . $arn . "\r\nToken:" . $token . "\r\n" . $errorMsg . "\r\n");
                    fclose($newFile);
                }
            }
            if (strpos($message, "No endpoint found for the target arn specified") !== false && $token != "") {
                try {
                    $updatedArn = $sns->createPlatformEndpoint(array('PlatformApplicationArn' => $appArn, 'Token' => $token));
                    $arn = $newArn = isset($updatedArn['EndpointArn']) ? $updatedArn['EndpointArn'] : "";
                    //update member detail with new arn
                    if ($newArn != "" && !empty($key) && $token != "") {
                        /* You can update arn into database for this member */
                    }
                } catch (Exception $e) {
                    $errorMsg = $e->getMessage();
                    $newFile = fopen("error_arn_fail.txt", "a+");
                    fwrite($newFile, "Member Id:" . $key . "\r\nToken:" . $token . "\r\n" . $errorMsg . "\r\n");
                    fclose($newFile);
                }
            }
            /* After handle error resed notification to this users */
            if (!empty($arn)) {
                try {
                    $publishRes = $sns->publish(array(
                        'Message' => '{ "GCM": "{\"data\": { \"message\": \"' . $push_content . '\" } }"}',
                        'MessageStructure' => 'json',
                        'TargetArn' => $arn
                    ));
                    $retArr[$key] = $publishRes->get("MessageId");
                } catch (Exception $e) {
                    $errorMsg = $e->getMessage();
                    $newFile = fopen("error_push_not_sent.txt", "a+");
                    fwrite($newFile, "Member Id:" . $key . "\r\nARN:" . $arn . "\r\nToken:" . $token . "\r\n" . $errorMsg . "\r\n");
                    fclose($newFile);
                }
            }
        } else {
            $retArr[$key] = $results[$key]['value']->get("MessageId");
        }
    }

    /* All member data get into one array to perform database operation */
    if (isset($retArr) && !empty($retArr)) {
        /* in $retArr you get each member amazon message id */
    }
}
票数 2
EN

Stack Overflow用户

发布于 2017-06-26 06:55:25

我建议使用publishAsync()方法。

代码语言:javascript
复制
$userArnCollection = array(
    'arn:XXX',
    'arn:YYY',
    'arn:ZZZ',
);
$sns = new Aws\Sns\SnsClient(array(
    'version' => 'latest',
    'key'     => my_aws_key,
    'secret'  => aws_secret,
    'region'  => region,
    'profile' => profile_name,
    'debug'   => false,
    'http'    => array('verify' => false)
));

foreach ($userArnCollection as $userArn) {
    $sns->publishAsync(array(
        'Message'          => '{ "GCM": "{\"data\": { \"message\": \" This is my message \"} }"}',
        'MessageStructure' => 'json',
        'TargetArn'        => $userArn
    ));
}

编辑

具有承诺处理的示例

代码语言:javascript
复制
$userArnCollection = array(
    'arn:XXX',
    'arn:YYY',
    'arn:ZZZ',
);
$sns = new Aws\Sns\SnsClient(array(
    'version' => 'latest',
    'key'     => my_aws_key,
    'secret'  => aws_secret,
    'region'  => region,
    'profile' => profile_name,
    'debug'   => false,
    'http'    => array('verify' => false)
));

$promises = array();
foreach ($userArnCollection as $userArn) {
    $promises[] = $sns->publishAsync(array(
        'Message'          => '{ "GCM": "{\"data\": { \"message\": \" This is my message \"} }"}',
        'MessageStructure' => 'json',
        'TargetArn'        => $userArn
    ));
}

$results = \GuzzleHttp\Promise\unwrap($promises);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44753314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档