0

すべてのユーザー (~15,000) にメッセージ (例: アップデートが利用可能) を送信したい。メッセージを送信するために、Google Cloud Messaging を使用して App Engine バックエンドを実装しました。

私は2つのデバイスでテストしました。両方にメッセージが届きました。しかし、Google ドキュメントにあるように、「GCM は、1 つのメッセージで最大 1,000 人の受信者をサポートしています。」

私の質問は、私の場合、残りの 14,000 人のユーザーに同じメッセージを送信する方法です。または、以下のコードはそれを処理しますか?

以下は、メッセージを送信するコードです

import com.google.android.gcm.server.Constants;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiNamespace;

import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;

import javax.inject.Named;

import static com.example.shani.myapplication.backend.OfyService.ofy;

/**
 * An endpoint to send messages to devices registered with the backend
 * <p/>
 * For more information, see
 * https://developers.google.com/appengine/docs/java/endpoints/
 * <p/>
 * NOTE: This endpoint does not use any form of authorization or
 * authentication! If this app is deployed, anyone can access this endpoint! If
 * you'd like to add authentication, take a look at the documentation.
 */
@Api(name = "messaging", version = "v1", namespace = @ApiNamespace(ownerDomain = "backend.myapplication.shani.example.com", ownerName = "backend.myapplication.shani.example.com", packagePath = ""))
public class MessagingEndpoint {
    private static final Logger log = Logger.getLogger(MessagingEndpoint.class.getName());

    /**
     * Api Keys can be obtained from the google cloud console
     */
    private static final String API_KEY = System.getProperty("gcm.api.key");

    /**
     * Send to the first 10 devices (You can modify this to send to any number of devices or a specific device)
     *
     * @param message The message to send
     */
    public void sendMessage(@Named("message") String message) throws IOException {
        if (message == null || message.trim().length() == 0) {
            log.warning("Not sending message because it is empty");
            return;
        }
        // crop longer messages
        if (message.length() > 1000) {
            message = message.substring(0, 1000) + "[...]";
        }
        Sender sender = new Sender(API_KEY);

         Message msg = new Message.Builder().addData("message", message).build();

        List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(1000).list();
        for (RegistrationRecord record : records) {
            Result result = sender.send(msg, record.getRegId(), 5);
            if (result.getMessageId() != null) {
                log.info("Message sent to " + record.getRegId());
                String canonicalRegId = result.getCanonicalRegistrationId();
                if (canonicalRegId != null) {
                    // if the regId changed, we have to update the datastore
                    log.info("Registration Id changed for " + record.getRegId() + " updating to " + canonicalRegId);
                    record.setRegId(canonicalRegId);
                    ofy().save().entity(record).now();
                }
            } else {
                String error = result.getErrorCodeName();
                if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
                    log.warning("Registration Id " + record.getRegId() + " no longer registered with GCM, removing from datastore");
                    // if the device is no longer registered with Gcm, remove it from the datastore
                    ofy().delete().entity(record).now();
                } else {
                    log.warning("Error when sending message : " + error);
                }
            }
        }
    }
}

同様の質問があることは知っていますが、私は Java 言語を使用しています。バックエンドでphp言語を使用している質問を見つけました。私には役に立たない!

  1. Google Cloud Messaging: 「すべての」ユーザーにメッセージを送信
  2. 複数のデバイスでプッシュ通知を送信する

App Engine+Google Cloud Messaging JAVA 言語の実装に成功した人はいますか?

以下のコード行で、1000 を 15,000 に置き換えると、問題は解決しますか?

List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(1000).list();

どうぞお早めにどうぞ。そして、私の英語で大変申し訳ありません.. 他の詳細が必要な場合は、お気軽にお問い合わせください。

御時間ありがとうございます。

4

2 に答える 2

1

いくつかの考慮事項、

1) 膨大な数のユーザーに通知を送信すると、かなりの時間がかかる可能性があります。タスク キューを使用して、60 秒の制限外で「オフライン」で実行される作業をキューに入れることを検討してください。

2) GCM の制限については、すべてのユーザーが必要であるが、GCM で一度に 1000 を許可する場合は、それらを 1000 のバッチに分割し、すべてのバッチのメッセージを個別に送信します。

両方の推奨事項を組み合わせると、1 回のリクエストですべてのユーザーを照会し、そのリストを分割して、一度に 1000 人のユーザーにメッセージを送信するだけのキューに入れる、かなりスケーラブルなプロセスが必要になります。

于 2015-04-18T13:21:06.240 に答える
1

以下の @jirungaray の回答の拡張は、すべての登録ユーザーに GCM メッセージを送信するためのコードです。

ここでは、Android から GCM サービスの各モバイル デバイスを登録し、それらのデバイス トークンをデータベースに保存していると仮定します。

public class GCM {
    private final static Logger LOGGER = Logger.getLogger(GCM.class.getName());
    private static final String API_KEY = ConstantUtil.GCM_API_KEY;
    public static void doSendViaGcm(List<String> tocken,String message) throws IOException {
        Sender sender = new Sender(API_KEY);
    // Trim message if needed.
    if (message.length() > 1000) {
      message = message.substring(0, 1000) + "[...]";
     }
     Message msg = new Message.Builder().addData("message", message).build();
    try{
    MulticastResult result = sender.send(msg, tocken, 5);
    }catch(Exception ex){
    LOGGER.severe("error is"+ex.getMessage());
    ex.printStackTrace();
    }
}

}

上記のコード スニペットでは、API_KEY を Google コンソール プロジェクトから取得できます。ここでは、既に 1 つのGoogle コンソール プロジェクトを作成し、GCM API を有効にしていると仮定します。

次のように API_KEY を生成できます

your_google_console_project>> Credentials>> Create New Key >> Server key >> GCM api へのアクセスを許可する IP アドレスを入力 [i used 0.0.0.0/0]

GCM クラスの doSendViaGcm(List tocken,String message) は、登録されているすべての Android モバイル デバイスにメッセージを送信するタスクを実行するようになりました。

ここList<String> token is array-list of all device tokenでメッセージが配信されます。これlist size以上はいけませthan 1000ん。そうしないと、http 呼び出しが失敗することに注意してください。

これがあなたに役立つことを願っています

于 2015-04-20T18:06:20.420 に答える