0

Я хочу отправить сообщение (например, доступное обновление) всем пользователям (~ 15 000). Я внедрил App Engine Backend with Google Cloud Messaging для отправки сообщения.App Engine Backend с Google Cloud Messaging отправляет сообщение более чем 1000 пользователям

Я тестировал на 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-язык для бэкэнд. так что не полезно для меня!

  1. Google Cloud Messaging: Send message to "all" users
  2. Sending Push Notification on multiple devices

Есть ли кто-нибудь, кто успешно реализовал App Engine + Google Cloud Messaging JAVA язык?

В приведенной ниже строке кода, если я заменю 1000 на 15 000 Будет ли она решить мою проблему?

List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(1000).list(); 

Пожалуйста, помогите как можно скорее. И очень жаль моего английского языка. Если кому-то нужна другая информация, вы можете спросить.

Спасибо за ваше время.

+0

, что происходит при запуске кода вы говорите может работать тогда? –

+0

@PaulCollingwood Когда я запускаю клиентский код на двух устройствах, все получили reg id, после чего я отправлял сообщения с appspot.com, все устройства получили сообщение. Благодарю. – Programmer

+0

Check [Мой вопрос/ответ] [1] Я сделал это таким образом, необходимо тестирование хотя [1]: http://stackoverflow.com/questions/29934331/push-notifications-for-1000 -devices-through-gcm-serverjava/29935914 # 29935914 – busted13

ответ

1

Несколько соображений,

1) Отправка уведомлений на возможно огромное количество пользователей может занять значительное время, рассмотреть возможность использования Task Queues очереди, что работа предстоит сделать «автономный режим» вне предела 60 сек.

2) Теперь, что касается предела GCM, если вам нужны все ваши пользователи, но GCM позволяет вам 1000 раз разделить их в партиях по 1000 и отправлять каждую партию сообщение отдельно.

Если вы объедините обе рекомендации, у вас должен быть достаточно масштабируемый процесс, когда вы запрашиваете для всех своих пользователей в 1 запросе, разделяете этот список и просто отправляете сообщение пользователям этим пользователям 1000 за раз.

+0

Hi jirungaray, Спасибо за ответ. Я согласен с вашими соображениями. Если вы можете дать мне образец кода, то это будет большой помощью. – Programmer

+0

У вас есть более простое решение пакетных запросов для 1000 пользователей? Я не знаю Task Queues. – Programmer

+0

Я могу придумать множество решений, не более простых, чем использование очередей. Очереди задач - это основная услуга для GAE, и вы обязательно должны прочитать о них в приведенной ссылке. Также, если вы не прибегаете к очередям или бэкэнд-процессам, ваше приложение не будет работать за пределами определенного количества пользователей. У вас уже есть код, вам просто нужно переместить отправляющую часть в другой сервлет и установить для нее очередь. Документы показывают, как это сделать за 5 минут. – jirungaray

1

Пристройка к @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(); 
    } 
} 

} 

В выше фрагмент кода api_key можно получить от проекта консоли Google, здесь я предполагаю, что вы уже создали один google console project и включить GCM API,

вы можете создать api_key следующим

your_google_console_project >> Учетные данные >> Создать новый ключ >> Сервер ключ >> введите IP-адрес, который вы хотите разрешить доступ к GCM api [i используется 0.0.0.0/0]

Теперь doSendViaGcm (Список tocken, String сообщение) класса GCM выполняет задачу отправки сообщений на все зарегистрировать андроид мобильных устройств

здесь List<String> token is array-list of all device token, на котором будут доставлены сообщения, помните об этом list size не должны более than 1000 или иначе http-вызов не удастся.

надеюсь, что это поможет вам спасибо

+0

Hi Dev Спасибо за ваш вклад. Извините, но я не понимаю эту часть, «сохраняя эти токены устройства в базе данных». Я не написал специальный код для хранения устройства tocken. Как я вижу в коде сервера App Engine, файл RegistrationEndpoint.java состоит из registerDevice(), listDevice(). Я думаю, что эти методы уже хранят регистрацию устройств. Нужно ли мне писать код для того же самого? Пожалуйста, уточните мои сомнения. – Programmer

+0

Кажется, вы используете оконечную точку облака в таком случае listDevice() должен просто работать нормально, но в этом случае вам нужно извлечь строку токена из объекта устройства. Позвольте мне спросить вас, откуда вы будете отправлять сообщения GCM из андроида или из приложения двигатель приложение? – Dev

+0

Я использую сервер HTTP-соединений, и для этого я использую Back-приложение для Google App Engine. Я отправляю сообщение от project_id.appspot.com/_ah/api/explorer. – Programmer