【发布时间】:2015-07-06 18:16:31
【问题描述】:
我的 GCM 端点源自 /github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/GcmEndpoints/root/src/main 中的代码。每个 Android 客户端设备 向端点注册。可以使用此代码向前 10 个注册的设备发送一条消息:
@Api(name = "messaging", version = "v1", namespace = @ApiNamespace(ownerDomain = "${endpointOwnerDomain}", ownerName = "${endpointOwnerDomain}", packagePath="${endpointPackagePath}"))
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(10).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);
}
}
}
}
}
上面的代码发送到前 10 个注册的设备。我想发送给所有注册的客户。根据http://objectify-appengine.googlecode.com/svn/branches/allow-parent-filtering/javadoc/com/googlecode/objectify/cmd/Query.html#limit(int) 设置limit(0) 来实现这一点。但我不相信由于内存限制或执行查询所需的时间,大量注册客户不会出现问题。 https://code.google.com/p/objectify-appengine/source/browse/Queries.wiki?repo=wiki 声明“游标让您在查询结果集中获取一个“检查点”,将检查点存储在其他地方,然后从您离开的地方继续。这通常与任务队列 API 结合使用以遍历大型数据集无法在单个请求的 60s 限制内处理”。
注意关于单个请求的 60s 限制的评论。
所以我的问题 - 如果我修改 /github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/GcmEndpoints/root/src/main 中的示例代码以通过替换 limit( 10) 使用limit(0),这对于大量对象是否会失败?如果它会失败,大概有多少个对象?
【问题讨论】:
标签: google-app-engine google-cloud-datastore objectify