通过 GCM 服务器推送超过 1000 台设备的通知(Java)
PUSH Notifications for >1000 devices through GCM Server(Java)
我有一个 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);
}
}
}
}
我们不能在 time.I 发送超过 1000 个推送通知搜索了很多但没有结果然后我用相同的方法将整个列表拆分为 1000 个项目的子列表并发送推送通知。
引用自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 的列表集合,而不是单个注册 ID。
我有一个 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);
}
}
}
}
我们不能在 time.I 发送超过 1000 个推送通知搜索了很多但没有结果然后我用相同的方法将整个列表拆分为 1000 个项目的子列表并发送推送通知。
引用自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 的列表集合,而不是单个注册 ID。