0

Je souhaite envoyer un message (par exemple, mise à jour disponible) à tous les utilisateurs (~ 15 000). J'ai mis en œuvre App Engine Backend with Google Cloud Messaging pour envoyer un message.Backend App Engine avec Google Cloud Messaging envoyant un message à plus de 1000 utilisateurs

J'ai testé sur 2 appareils. J'ai un message sur les deux. Mais comme le dit google docs "GCM prend en charge jusqu'à 1000 destinataires pour un seul message."

Ma question est de savoir comment envoyer un même message à rester 14.000 utilisateurs dans mon cas? Ou le code ci-dessous s'en occupera?

est Ci-dessous le code qui envoie un message

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

Je sais qu'il ya des questions simillar mais j'utilise langage Java. J'ai trouvé des questions qui utilisent le langage PHP au backend. donc pas utile pour moi!

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

Est-ce qu'il ya quelqu'un qui a mis en œuvre avec succès App Engine + Google Cloud Messaging langage Java?

Dans la ligne de code ci-dessous si je remplace 1000 par 15 000 Réservera-t-il mon problème?

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

S'il vous plaît, veuillez nous aider dès que possible. Et très désolé pour mon anglais .. Si quelqu'un a besoin d'autres détails, vous êtes invités à demander.

Merci pour votre temps.

+0

ce qui se passe lorsque vous exécutez le code que vous dites pourrait fonctionner alors? –

+0

@PaulCollingwood Quand j'ai couru le code de client sur 2 appareils tout a eu l'identification de reg alors j'ai envoyé des messages de appspot.com tous les dispositifs ont reçu le message. Merci. – Programmer

+0

Cochez la case [Ma question/réponse] [1] Je l'ai fait de cette façon, a besoin d'un test si [1]: http://stackoverflow.com/questions/29934331/push-notifications-for-1000 -devices-à travers-gcm-serverjava/29935914 # 29935914 – busted13

Répondre

1

Quelques considérations,

1) Envoi de notifications à un nombre énorme d'utilisateurs peut-être pourrait prendre beaucoup de temps, pensez à utiliser la file d'attente Task Queues pour que le travail à faire « hors ligne » en dehors de la limite de 60 sec. 2) Maintenant, en ce qui concerne la limite GCM, si vous avez besoin de tous vos utilisateurs, mais que GCM vous en autorise 1000 à la fois, il suffit de les fractionner en lots de 1000 et d'envoyer chaque lot séparément. Si vous combinez les deux recommandations, vous devriez avoir un processus assez évolutif où vous interrogez tous vos utilisateurs en 1 requête, divisez cette liste et faites simplement la queue en envoyant le message à ces utilisateurs 1000 à la fois.

+0

Salut jirungaray, Merci pour la réponse. Je suis d'accord avec vos considérations. Si vous pouvez me donner un exemple de code, ce sera une aide précieuse. – Programmer

+0

Avez-vous une solution plus simple pour traiter les demandes par lot sur 1000 utilisateurs? Je ne connais pas les files d'attente de tâches. – Programmer

+0

Je peux penser à beaucoup de solutions, aucune plus simple que l'utilisation des files d'attente. Les files d'attente de tâches sont un service de base pour GAE et vous devriez certainement lire à leur sujet dans le lien que j'ai fourni. Aussi, si vous n'avez pas recours à des files d'attente ou des processus de backend votre application ne fonctionnera pas au-delà d'un certain nombre d'utilisateurs. Vous avez déjà le code, il vous suffit de déplacer la partie émettrice dans une autre servlet et d'en faire une file d'attente. Les docs vous montrent comment faire cela en 5 min. – jirungaray

1

Extension à la réponse @jirungaray est le code ci-dessous pour envoyer des messages GCM à tous les utilisateurs enregistrés,

Ici, je suppose que d'Android que vous enregistrez chaque-appareils mobiles pour les services de GCM et de stocker les jetons d'appareil dans la base de données.

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

} 

Dans l'extrait de code ci-dessus api_key peut obtenir à partir du projet de console google, ici, je suppose que vous avez déjà créé un google console project et activer api GCM,

vous pouvez générer api_key comme suit

your_google_console_project >> Credentials >> Créer une nouvelle clé >> Serveur key >> entrez l'adresse IP que vous souhaitez autoriser accéder à l'API GCM [J'ai utilisé 0.0.0.0/0]

maintenant doSendViaGcm (Liste tocken, message String) de classe GCM exécute la tâche d'envoyer des messages à tous enregistrer les appareils mobiles Android

ici List<String> token is array-list of all device token sur lequel les messages seront livrés, rappelez-vous ce list size ne devrait pas plus than 1000 ou bien L'appel http échouera.

espère que cela vous aidera grâce

+0

Salut Dev Merci pour votre contribution. Désolé mais je ne comprends pas cette partie "stocker ces jetons de périphérique dans la base de données." Je n'ai pas écrit de code spécifique pour stocker le tocken de l'appareil. Comme je peux le voir dans le code App Engine Server, le fichier RegistrationEndpoint.java est constitué de registerDevice(), listDevice(). Je pense que ces méthodes stockent déjà les identifiants de périphériques. Ai-je besoin d'écrire un code pour le même? S'il vous plaît clarifier mon doute. – Programmer

+0

Il semble que vous utilisez le point de terminaison cloud dans ce cas listDevice() devrait fonctionner correctement mais dans ce cas, vous devez extraire la chaîne de token de Device Object .Let vous demander d'où vous allez envoyer des messages GCM à partir d'Android application du moteur ?? – Dev

+0

J'utilise le serveur de connexion HTTP et pour cela j'utilise Google App Engine Backend. J'envoie un message de project_id.appspot.com/_ah/api/explorer. – Programmer