【问题标题】:GCM: MulticastResult - which result is from which device?GCM:MulticastResult - 哪个结果来自哪个设备?
【发布时间】:2012-07-21 16:10:16
【问题描述】:

按照GCM: Getting Started 指南的最后一部分,在收到结果后需要做一些记账。

引自指南:

现在需要解析结果并在以下情况下采取适当的措施:

  • 如果消息已创建,但结果返回了规范的注册 ID,则需要替换当前注册
    带有规范的 ID。
  • 如果返回的错误是 NotRegistered,则需要删除该注册 ID,因为应用程序已从 设备。

这是处理这两个条件的代码 sn-p:

if (result.getMessageId() != null) {
 String canonicalRegId = result.getCanonicalRegistrationId();
 if (canonicalRegId != null) {
   // same device has more than on registration ID: update database
 }
} else {
 String error = result.getErrorCodeName();
 if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
   // application has been removed from device - unregister database
 }
}

以上指南指的是单个结果,而不是多播情况。 我不确定如何处理多播情况:

    ArrayList<String> devices = new ArrayList<String>();

    for (String d : relevantDevices) {
        devices.add(d);
    }

    Sender sender = new Sender(myApiKey);
    Message message = new Message.Builder().addData("hello", "world").build();
    try {
        MulticastResult result = sender.send(message, devices, 5);

        for (Result r : result.getResults()) {
            if (r.getMessageId() != null) {
                String canonicalRegId = r.getCanonicalRegistrationId();
                if (canonicalRegId != null) {
                    // same device has more than on registration ID: update database
                    // BUT WHICH DEVICE IS IT?
                }
            } else {
                String error = r.getErrorCodeName();
                if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
                    // application has been removed from device - unregister database
                    // BUT WHICH DEVICE IS IT?
                }
            }
        }
    } catch (IOException ex) {
        Log.err(TAG, "sending message failed", ex);
    }

我提交了一份设备列表,并收到了一份结果列表。 Result 对象不包含注册 id,但如果第一个已过时,则仅包含规范 id。 如果这两个列表相互关联(即保留顺序和大小),则没有记录。

我如何确定哪个结果是指哪个设备?

-- 更新

我已将解决方案的 sn-p 粘贴到下面的单独答案中

【问题讨论】:

    标签: android google-cloud-messaging


    【解决方案1】:

    结果按照您发送到 GCM 服务器的 registration_id 数组的顺序排列。例如如果您的registration_ids 是:

    [id1, id4, id7, id8]
    

    那么你得到的结果数组对于 id1、id4、id7 和 id8 将具有相同的顺序。

    您只需要相应地解析每个结果,例如如果第二个结果有 'message_id' 和 'registration_id' of 'id9',你知道 'id4' 现在已经过时了,应该被 id9 取代。

    【讨论】:

    【解决方案2】:

    为了方便读者,这里是一个处理多个设备响应的 sn-p

    public void sendMessageToMultipleDevices(String key, String value, ArrayList<String> devices) {
    
            Sender sender = new Sender(myApiKey);
            Message message = new Message.Builder().addData(key, value).build();
            try {
                MulticastResult result = sender.send(message, devices, 5);
                MTLog.info(TAG, "result " + result.toString());
    
    
                for (int i = 0; i < result.getTotal(); i++) {
                    Result r = result.getResults().get(i);
    
                    if (r.getMessageId() != null) {
                        String canonicalRegId = r.getCanonicalRegistrationId();
                        if (canonicalRegId != null) {
                            // devices.get(i) has more than on registration ID: update database
    
                        }
                    } else {
                        String error = r.getErrorCodeName();
                        if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
                            // application has been removed from devices.get(i) - unregister database
                        }
                    }
                }
            } catch (IOException ex) {
                MTLog.err(TAG, "sending message failed", ex);
            }
        }
    

    【讨论】:

    • Result 类有 3 个字段:messageId、canonicalRegistrationId 和 errorCode。所有相关案例都包含在代码 sn-p 中。 canonicalRegistrationId 是一个更新的 gcm 密钥。
    • devices.get(i) has more than one registration ID: update database - 在这里应该做什么?从数据库中删除 devices.get(i) 或从结果中删除具有 canonicalRegistrationId 的设备?或者检查数据库中是否存在具有 canonicalRegistrationId 的设备?如果是,则删除另一个,如果为false,则更改另一个的id?
    • 您应该用新的 canonicalRegistrationId = new regId 替换旧 regId 的 devices.get(i)。你可能已经有了新的 regId,如果你用新的 regId 注册了同一个用户(认为它是新用户),然后尝试用旧的 id 联系到他。
    【解决方案3】:

    此解决方案由谷歌开发者示例 GCM Demo application 完成 注意多播句柄的 asyncSend

    List<GcmUsers> devices=SearchRegisterdDevicesByCourseCommand.execute(instructorId, courseId);
        String status;
        if ( devices.equals(Collections.<GcmUsers>emptyList())) {    
          status = "Message ignored as there is no device registered!";
        } else {
          // NOTE: check below is for demonstration purposes; a real application
          // could always send a multicast, even for just one recipient
          if (devices.size() == 1) {
            // send a single message using plain post
            GcmUsers gcmUsers = devices.get(0);
            Message message = new Message.Builder().build();
            Result result = sender.send(message, gcmUsers.getGcmRegid(), 5);
            status = "Sent message to one device: " + result;
          } else {
            // send a multicast message using JSON
            // must split in chunks of 1000 devices (GCM limit)
            int total = devices.size();
            List<String> partialDevices = new ArrayList<String>(total);
            int counter = 0;
            int tasks = 0;
            for (GcmUsers device : devices) {
              counter++;
              partialDevices.add(device.getGcmRegid());
              int partialSize = partialDevices.size();
              if (partialSize == MULTICAST_SIZE || counter == total) {
                asyncSend(partialDevices);
                partialDevices.clear();
                tasks++;
              }
            }
            status = "Asynchronously sending " + tasks + " multicast messages to " +
                total + " devices";
          }
        }
        req.setAttribute(HomeServlet.ATTRIBUTE_STATUS, status.toString());
    
    
    
    
    
    
    private void asyncSend(List<String> partialDevices) {
        // make a copy
        final List<String> devices = new ArrayList<String>(partialDevices);
        threadPool.execute(new Runnable() {
    
          public void run() {
            Message message = new Message.Builder().build();
            MulticastResult multicastResult;
            try {
              multicastResult = sender.send(message, devices, 5);
            } catch (IOException e) {
              logger.log(Level.SEVERE, "Error posting messages", e);
              return;
            }
            List<Result> results = multicastResult.getResults();
            // analyze the results
            for (int i = 0; i < devices.size(); i++) {
              String regId = devices.get(i);
              Result result = results.get(i);
              String messageId = result.getMessageId();
              if (messageId != null) {
                logger.fine("Succesfully sent message to device: " + regId +
                    "; messageId = " + messageId);
                String canonicalRegId = result.getCanonicalRegistrationId();
                if (canonicalRegId != null) {
                  // same device has more than on registration id: update it
                  logger.info("canonicalRegId " + canonicalRegId);
                  Datastore.updateRegistration(regId, canonicalRegId);
                }
              } else {
                String error = result.getErrorCodeName();
                if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
                  // application has been removed from device - unregister it
                  logger.info("Unregistered device: " + regId);
                  Datastore.unregister(regId);
                } else {
                  logger.severe("Error sending message to " + regId + ": " + error);
                }
              }
            }
          }});
      }
    

    【讨论】:

    • 您链接到的示例应用程序中有一条注释:“本文档中的信息已被 GCM 服务器和 GCM 客户端取代。请使用 GoogleCloudMessaging API 而不是 GCM 客户端帮助程序库。GCM服务器帮助程序库仍然有效。”。你的答案是最新的吗?
    • 它的 2 周更新看起来谷歌已经更新了库并且演示还没有更新:)
    猜你喜欢
    • 2019-09-21
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2013-08-06
    • 2021-11-14
    • 1970-01-01
    相关资源
    最近更新 更多