我想向所有用户发送消息(例如,可用更新)(〜15,000)。 我已经使用Google Cloud Messaging实现了App Engine后端来发送消息。
我已经在2种设备上进行了测试。 都收到消息。 但是正如google docs所说的那样, “ GCM支持单个消息最多支持1000个收件人。”
我的问题是在我的情况下如何向其余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语言的问题。 所以对我没有帮助!
是否有人成功实现了App Engine + Google Cloud Messaging JAVA语言?
在下面的代码行中,如果我将1000替换为15,000,它将解决我的问题吗?
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(1000).list();
请尽快提供帮助。 非常抱歉我的英语。如果有人需要其他详细信息,欢迎您提出。
谢谢你的时间。
一些注意事项,
1)向可能数量庞大的用户发送通知可能会花费大量时间,请考虑使用“ 任务队列 ”将在60秒以内“离线”完成的工作排队。
2)现在,对于GCM限制,如果您需要所有用户,但GCM一次允许您有1000个,只需将它们分成1000个批次,并分别向每个批次发送一条消息。
如果将这两个建议结合在一起,则应该有一个相当可扩展的过程,您可以在1个请求中查询所有用户,拆分该列表,然后仅一次将消息发送给这些用户1000个队列。
以下@jirungaray答案的扩展名是用于将GCM消息发送给所有注册用户的代码,
在这里,我假设从android您正在为GCM服务注册每个移动设备并将这些设备令牌存储在数据库中。
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();
}
}
}
在上面的代码段中,可以从Google控制台项目中获取API_KEY,这里我假设您已经创建了一个Google控制台项目并启用了GCM api,
您可以如下生成API_KEY
your_google_console_project >>凭证>>创建新密钥>>服务器密钥>>输入您要允许访问GCM api的IP地址[我使用了0.0.0.0/0]
现在,GCM类的doSendViaGcm(List tocken,String message)执行向所有注册的android移动设备发送消息的任务
这里List<String> token is array-list of all device token
将在其上传递消息List<String> token is array-list of all device token
,请记住,此list size
不能than 1000
,否则http调用将失败。
希望这对您有所帮助