PUSH Notifications for >1000 devices through GCM S

2020-07-26 13:45发布

问题:

I have a GCM-backend Java server and I'm trying to send to all users a notification msg. Is my approach right? To just split them into 1000 each time before giving the send request? Or is there a better approach?

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

      }
   }

The regIdTrim method

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

The sendMsg method

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

回答1:

Quoting from Google Docs:

GCM is support for up to 1,000 recipients for a single message. This capability makes it much easier to send out important messages to your entire user base. For instance, let's say you had a message that needed to be sent to 1,000,000 of your users, and your server could handle sending out about 500 messages per second. If you send each message with only a single recipient, it would take 1,000,000/500 = 2,000 seconds, or around half an hour. However, attaching 1,000 recipients to each message, the total time required to send a message out to 1,000,000 recipients becomes (1,000,000/1,000) / 500 = 2 seconds. This is not only useful, but important for timely data, such as natural disaster alerts or sports scores, where a 30 minute interval might render the information useless.

Taking advantage of this functionality is easy. If you're using the GCM helper library for Java, simply provide a List collection of registration IDs to the send or sendNoRetry method, instead of a single registration ID.



回答2:

We can not send more than 1000 push notification at time.I searched a lot but not result then i did this with same approach split whole list in sub lists of 1000 items and send push notification.