【问题标题】:JavaPNS on GAE: Only receiving every second push notificationGAE 上的 JavaPNS:仅接收每秒一次的推送通知
【发布时间】:2014-01-13 12:19:11
【问题描述】:

我正在尝试将推送通知添加到 Google App Engine 服务器,但我遇到了一个奇怪的问题,即设备仅每隔一秒接收一次推送通知。

我已经设置了一个推送队列来在后端发送通知。每个实例的第一个请求创建一个后台线程,该线程将推送和发送它们排队。然后每个推送请求将请求添加到队列中,等待推送发送,然后使用代码 200 表示成功或代码 500 表示失败。这是我的后台线程代码:

void doSendThread() {

    // Open certificate (certificate is a class URL var)
    InputStream cert = certificate.openStream();

    // Connect to Apple Push service (password and apnsManager are class vars)
    AppleNotificationServer appleServer = new AppleNotificationServerBasicImpl(cert, password, ConnectionToAppleServer.KEYSTORE_TYPE_PKCS12, "gateway.push.apple.com", 2195);
    apnsManager = new PushNotificationManager();
    apnsManager.initializeConnection(appleServer);

    // Send loop
    while (true) {

        // Wait for a bit
        Thread.sleep(500);

        // Check for new pushes in queue (pushQueue is a class ArrayDequeue var)
        while (!pushQueue.isEmpty()) {

            // Get next push data (PushData is a custom class that holds the push notification state)
            PushData data = pushQueue.poll();

            // Send data (the HTTP request thread stops waiting when data.done is true)
            sendPushData(data);
            data.done = true;

        }

    }

    // There's also some feedback checking stuff here which I've left out
    ...

}

void sendPushData(PushData) {

    try {

        // Get tokens
        Logger.getLogger(PushManager.class.getName()).log(Level.INFO, "Sending push...");
        List<Device> devices = Devices.asDevices(data.tokens);

        // Create payload
        PushNotificationPayload payload = PushNotificationPayload.complex();
        if (data.text.length() > 0)
            payload.addAlert(data.text);
        if (data.badge > 0)
            payload.addBadge(data.badge);
        if (data.sound.length() > 0)
            payload.addSound(data.sound);

        // Go through devices and send each push
        for (Device dev : devices) {

            // Send payload and don't close the connection
            PushedNotification pn = apnsManager.sendNotification(dev, payload, false);

            // Check for error (HTTP thread returns 500 if data.error is true)
            if (!pn.isSuccessful())
                data.error = true;

            // Log error
            if (pn.getException() != null)
                Logger.getLogger(PushManager.class.getName()).log(Level.SEVERE, "Push error: " + pn.getException().getMessage());

        }

    } catch (Exception e) {
        Logger.getLogger(PushManager.class.getName()).log(Level.SEVERE, "Push error: " + e.getMessage());
        e.printStackTrace();
        disconnect(); // <- Disconnects the apnsManager and shuts down the thread, the next push request will create a new thread and reconnect
        data.error = true;
    }

}

在 GAE 上进行日志记录很困难,因为只有在实例关闭后日志才会通过后台线程,但如果我使用应用发送 5 次推送然后关闭实例,这就是我的日志:

W 2014-01-13 13:41:18.028 [s~*****chat/push-notification-worker.373021320690690677].<stderr>: log4j:WARN No appenders could be found for logger (javapns.communication.Connecti
W 2014-01-13 13:41:18.028 [s~*****chat/push-notification-worker.373021320690690677].<stderr>: log4j:WARN Please initialize the log4j system properly.
W 2014-01-13 13:41:18.028 [s~*****chat/push-notification-worker.373021320690690677].<stderr>: log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more inf
I 2014-01-13 13:41:19.222 com.*****apps.*****Server.Push.PushManager sendPushData: Sending push...
I 2014-01-13 13:41:23.027 com.*****apps.*****Server.Push.PushManager sendPushData: Sending push...
I 2014-01-13 13:41:23.663 com.*****apps.*****Server.Push.PushManager sendPushData: Sending push...
I 2014-01-13 13:41:24.225 com.*****apps.*****Server.Push.PushManager sendPushData: Sending push...
I 2014-01-13 13:41:24.790 com.*****apps.*****Server.Push.PushManager sendPushData: Sending push...
I 2014-01-13 13:42:25.022 com.*****apps.*****Server.Push.PushManager disconnect: Shutting down push manager...

...所以看起来它正在发送所有 5 个,但我只收到第二个和第四个通过设备。真正奇怪的是,每次推送实际上发送 2 次推送,因为我有 2 台设备(因此实际上向 Apple 发送了 10 条推送通知),并且它要么同时接收消息,要么不接收消息,永远不会只接收一个。

【问题讨论】:

  • 您要发送多少条消息?日志显示 5,但您写道,向 Apple 发送了 10 条推送通知。那 5 条消息是否发送到同一个设备令牌? (因为你说你只有两个设备)。如果您在短时间内向同一设备发送多条消息,Apple 很可能只发送其中的一部分。这是预期的行为。
  • 嗨,是的,它们被发送到相同的设备令牌...如果这是预期的行为,我必须让服务器延迟消息到相同的令牌吗?如果是这样,必须延迟多长时间?

标签: java google-app-engine apple-push-notifications javapns


【解决方案1】:

在短时间内向同一设备发送多个通知可能会导致仅发送部分通知。在发送到同一设备的消息之间强制执行一些任意延迟(这可能足够也可能不够)并不是一个好习惯。您的应用必须能够处理不接收您发送给它的所有通知(通过与您的服务器同步)。

以下是 Apple 的 tech note 对此的评价:

收到了一些通知,但不是全部

如果您要向同一设备发送多个通知,或者 计算机在短时间内,推送服务将发送 只有最后一个。

原因如下。设备或计算机确认收到每个 通知。在推送服务收到该确认之前,它 只能假设设备或计算机已离线一段时间 原因并将通知存储在服务质量 (QoS) 中 排队等待将来的重新交付。这里的往返网络延迟是 当然是一个主要因素。

如本地和推送通知编程指南中所述, QoS 队列为每个设备或计算机的每个应用程序保存一个通知。 如果服务在 队列已发送,新的通知会覆盖之前的通知。

所有这些都指出,意图是通知 向应用表明感兴趣的东西在 提供商,并且应用程序应与提供商签入以获取 细节。通知不应包含不包含的数据 在其他地方可用,它们也不应该是有状态的。

任何未立即发送的推送通知都已排队等待 由于您的设备未连接到 服务。 “立即”当然需要为您的 连接考虑在内。异常情况将超过 60 秒,因为 APN 将在此时超时。

【讨论】:

  • 谢谢,该应用程序已经单独与服务器同步,但现在我已经添加了更多人使用不同设备进行测试,它运行良好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
相关资源
最近更新 更多