我遇到了与
this相同的问题.我将尝试提供更多信息.
我正在使用Play Framework,用Java编写.我写了一个名为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.
>还有其他人遇到过这个问题吗?我在网上发现了一些有同样问题的人,但到目前为止还没有找到解决办法.
>我可以尝试解决的任何建议吗?
>我应该继续增加尝试次数吗?