经过6次尝试后,无法将JSON请求发布到GCM

我遇到同样的问题。 我会尽力提供更多信息。

我正在使用Java编写的Play Framework。 我写了一个名为PushNotificationQueue的插件。 PushNotificationQueue同时运行iOS和Android推送消息队列。 下面,作为参考,是我的GCM实施。

public class AndroidPushNotificationQueue {

  // (constructors and fields not included for brevity)
  // constructor starts a daemon thread

/**
* Sends a notification. 
* @param notifyKeys - device tokens
* @param data - data to send
**/
public void sendNotification(List<String> notifyKeys, Map<String, String> data) {       
    if (notifyKeys.size() == 0) {
        return;
    }

    Builder b = new Message.Builder();
    if (data != null) {
        for (String key : data.keySet()) {
            b.addData(key, data.get(key));
        }
    }
    if (testMode) {
        b.dryRun(true);
    }
    Message message = b.build();
    queue.add(new Notification(notifyKeys, message));
}

public void stop() {
    stopped = true;
    sendingThread.interrupt();
}

private class SendNotificationRunner implements Runnable {

    @Override
    public void run() {
        while (true) {
            try {
                sendNotifications();
                //TODO: handle errors
            } catch (InterruptedException e) {
                if (stopped)    break;
                Logger.error("Error processing android notification", e);
            } catch (InvalidRequestException e) {
                if (stopped)    break;
                Logger.error("Error processing android notification", e);
            } catch (IOException e) {
                if (stopped)    break;
                Logger.error("Error processing android notification", e);
            } catch (Exception e) {
                if (stopped)    break;
                Logger.error("Unexpected Exception in Android Notification thread", e);
            }
        }
        Logger.info("Stopping Android push queue");
    }

    private void sendNotifications() throws IOException, InterruptedException, InvalidRequestException {

        Notification n = queue.take(); // will wait until an element becomes available
        MulticastResult result = sender.send(n.message, n.notifyKeys, NUM_RETRIES);
        List<Result> results = result.getResults();

        for (int i = 0; i < results.size(); ++i) {
            Result r = results.get(i);
            String mId = r.getMessageId();
            String notifyKey = n.notifyKeys.get(i);

            if (mId == null) {
                String error = r.getErrorCodeName();
                if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
                    removeDeadRegistration(notifyKey);
                } else {
                    //TODO: something better when error occurs
                    Logger.error("Error sending android notification to " + notifyKey + ": " + error);
                }
            } else {
                String newNotifyKey = r.getCanonicalRegistrationId();
                if (newNotifyKey != null && !newNotifyKey.equals(notifyKey)) {
                       // do something to handle this error case - not included for brevity
                }
            }
        }
    }

}

这有效。 大多数时候我收到以下错误。

java.io.IOException: Could not post JSON requests to GCM after 6 attempts
  at com.google.android.gcm.server.Sender.send(Sender.java:319) ~[classes/:na]
  at utils.AndroidPushNotificationQueue$SendNotificationRunner.sendNotifications(AndroidPushNotificationQueue.java:131) ~[classes/:na]
  at utils.AndroidPushNotificationQueue$SendNotificationRunner.run(AndroidPushNotificationQueue.java:103) ~[classes/:na]
  at java.lang.Thread.run(Thread.java:745) [na:1.7.0_55]
  [debug] application - Endpoint - BaseStationAuth.getUsername

我做了一些挖掘,并在GCM实施中发现了这一点。

/**
   * Sends a message to one device, retrying in case of unavailability.
   *
   * <p>
   * <strong>Note: </strong> this method uses exponential back-off to retry in
   * case of service unavailability and hence could block the calling thread
   * for many seconds.
   *
   * @param message message to be sent, including the device's registration id.
   * @param registrationId device where the message will be sent.
   * @param retries number of retries in case of service unavailability errors.
   *
   * @return result of the request (see its javadoc for more details).
   *
   * @throws IllegalArgumentException if registrationId is {@literal null}.
   * @throws InvalidRequestException if GCM didn't returned a 200 or 5xx status.
   * @throws IOException if message could not be sent.
   */
  public Result send(Message message, String registrationId, int retries)
      throws IOException {
    int attempt = 0;
    Result result = null;
    int backoff = BACKOFF_INITIAL_DELAY;
    boolean tryAgain;
    do {
      attempt++;
      if (logger.isLoggable(Level.FINE)) {
        logger.fine("Attempt #" + attempt + " to send message " +
            message + " to regIds " + registrationId);
      }
      result = sendNoRetry(message, registrationId);
      tryAgain = result == null && attempt <= retries;
      if (tryAgain) {
        int sleepTime = backoff / 2 + random.nextInt(backoff);
        sleep(sleepTime);
        if (2 * backoff < MAX_BACKOFF_DELAY) {
          backoff *= 2;
        }
      }
    } while (tryAgain);
    if (result == null) {
      throw new IOException("Could not send message after " + attempt +
          " attempts");
    }
    return result;
  }

我有不同的尝试次数--5,10,15。

  • 有其他人遇到这个问题吗? 我发现有几个人在网上遇到同样的问题,但至今还没有找到解决方案。
  • 对我可以尝试解决的事情有任何建议?
  • 我应该不断增加尝试次数吗?

  • 我有同样的问题。 但修复它。

    1.我认为只需编辑'Sender.BACKOFF_INITIAL_DELAY = 1000;'到'Sender.BACKOFF_INITIAL_DELAY = 10000'的间隔时间变量; 在com.google.android.gcm.server的Sender.java中。

    你可以阅读Sender.java文件。 它是开源的。

    2.只要输入gcm有效载荷,我就改变了collaps_key值。 我认为谷歌服务器不接受collaps_key的特殊字符。 “。”,“,”,任何alpabet。

    祝你好运。


    清除GCM服务器配置中接受的所有IP地址(允许来自任何IP)为我解决了这个问题。 由于密钥已被使用,因此限制IP地址(大多数情况下)是不必要的预防措施。


    我的应用程序也抛出了异常消息“GCM - 无法在6次尝试后向GCM发布JSON请求”。 所以我在sendNoRetry(...)方法调用中的post(...)方法调用(Sender.java的第190行)中设置了一个断点,并且四处走动以获得有关响应的一些有用信息。

    在我的情况下,我得到了一个401 http状态码,因为我使用了错误的api键。

    链接地址: http://www.djcxy.com/p/81485.html

    上一篇: Could not post JSON requests to GCM after 6 attempts

    下一篇: Workaround for lack of return type covariance when overriding virtual methods