0

我想向所有用户(~15,000)发送一条消息(例如可用更新)。我已经使用 Google Cloud Messaging 实现了 App Engine 后端来发送消息。

我已经在 2 台设备上进行了测试。两者都有消息。但正如谷歌文档所说,“GCM 支持多达 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. 谷歌云消息:向“所有”用户发送消息
  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

Extension to the @jirungaray answer below is code for sending GCM messages to all registered users,

Here I assume that from android you are registering each mobile-devices for GCM services and storing those device tokens in database.

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();
    }
}

}

In above code snippet API_KEY can be obtain from google console project ,here I assume that you have already created one google console project and enable GCM api,

you can generate API_KEY as follows

your_google_console_project>> Credentials>> Create New Key >> Server key >> enter ip address Which you want to allow access to GCM api[i used 0.0.0.0/0]

Now doSendViaGcm(List tocken,String message) of GCM class performs task of sending messages to all register android mobile devices

here List<String> token is array-list of all device token on which messages will be delivered ,remember this list size should not more than 1000 or else http call will fail.

hope this will help you thanks

于 2015-04-20T18:06:20.420 回答