java - 通过 GCM Server(Java) 为 >1000 台设备推送通知

标签 java android google-cloud-messaging

我有一个 GCM 后端 Java 服务器,我正在尝试向所有用户发送通知消息。我的做法对吗?每次在发出发送请求之前将它们分成 1000 个?或者有更好的方法吗?

    public void sendMessage(@Named("message") String message) throws IOException {

    int count = ofy().load().type(RegistrationRecord.class).count();

    if(count<=1000) {
        List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(count).list();
        sendMsg(records,message);
    }else
    {
        int msgsDone=0;
        List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).list();

        do {
            List<RegistrationRecord> regIdsParts = regIdTrim(records, msgsDone);
            msgsDone+=1000;
            sendMsg(regIdsParts,message);
        }while(msgsDone<count);

      }
   }

regIdTrim 方法

   private List<RegistrationRecord> regIdTrim(List<RegistrationRecord> wholeList, final int start) {

    List<RegistrationRecord> parts = wholeList.subList(start,(start+1000)> wholeList.size()? wholeList.size() : start+1000);
    return parts;
}

sendMsg 方法

    private void sendMsg(List<RegistrationRecord> records,@Named("message") String message) throws IOException {

    if (message == null || message.trim().length() == 0) {
        log.warning("Not sending message because it is empty");
        return;
    }

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

    // crop longer messages
    if (message.length() > 1000) {
        message = message.substring(0, 1000) + "[...]";
    }
    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);
            }
        }
    }
}

最佳答案

引用自Google Docs :

GCM 支持单条消息最多 1,000 个收件人。此功能使向整个用户群发送重要消息变得更加容易。例如,假设您有一条消息需要发送给 1,000,000 个用户,而您的服务器每秒可以处理发送大约 500 条消息。如果您仅向一个收件人发送每条消息,则需要 1,000,000/500 = 2,000 秒,即大约半小时。但是,如果每条消息附加 1,000 个收件人,则将消息发送给 1,000,000 个收件人所需的总时间变为 (1,000,000/1,000)/500 = 2 秒。这不仅有用,而且对于及时获取数据很重要,例如自然灾害警报或体育比分,其中 30 分钟的间隔可能会使信息变得毫无用处。

利用此功能很容易。如果您使用的是 GCM helper library for Java ,只需向 send 或 sendNoRetry 方法提供注册 ID 的 List 集合,而不是单个注册 ID。

关于java - 通过 GCM Server(Java) 为 >1000 台设备推送通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29934331/

相关文章:

android - Kotlin Map 项目列表流

android - 在某些情况下,Android 中 GCM ID 不可用的原因是什么

java - Rally-rest-api v2.21 updateCollection 无法工作

java - gpg --list-keys 为空但文件解密 bouncycaSTLe 加密文件

android - 哪个是最好的移动Web应用程序开发框架

java - 如何有效管理Android应用程序的内存(堆)

ios - 处理应用程序未运行时将显示的推送通知

curl - 使用 GCM 推送通知发布数据

java - 带有 Tomcat 的简单 JAX-RS - 404 未找到(无 web.xml)

java - iText 填充我的堆大小导致应用程序因 OOM 崩溃