9

如果我正在向设备发送通知,并且该设备处于脱机状态,我会得到如下信息:

错误:不可用

我必须重新发送。

我的问题是:

GCM 服务器是否会将这些通知保留在队列中,并在设备在线时自动重新发送?或者它必须完全由我处理。

因为如果 GCM 服务器要自动发送它们(一旦设备在线),在它实际发送通知之前,我的服务器会假定它们已经发送。如何跟踪通知重新发送成功的时间?

我可能会在我的服务器端标记通知不是通过查看发送的,Unavailable error message但是一旦 GCM 成功发送通知,我就无法确定如何将它们标记为已发送。

谢谢你

4

2 回答 2

11

A/c to documentation--- 当第 3 方服务器向 GCM 发布消息并收到返回的消息 ID 时,这并不意味着消息已经传送到设备。相反,这意味着它已被接受交付。消息被接受后会发生什么取决于许多因素。

如果设备已连接但空闲,消息仍将立即传递,除非 delay_while_idle 标志设置为 true。否则,它将存储在 GCM 服务器中,直到设备唤醒。这就是 collapse_key 标志发挥作用的地方:如果已经存储了具有相同折叠密钥(和注册 ID)并等待传递的消息,则旧消息将被丢弃,新消息将取而代之(即,旧消息将被新消息折叠)。但是,如果未设置折叠键,则新旧消息都将被存储以供将来传递。

注意:在不折叠的情况下可以存储多少消息是有限制的。该限制当前为 100。如果达到限制,则丢弃所有存储的消息。

于 2013-06-04T06:58:09.290 回答
2

我所做的是将推送指示有效负载分开。在我的 GCM 消息中,我只包含有效负载的 URI,并且我将有效负载存储在一个数据库表中,该数据库表可通过消息中的 URI 访问。

当客户端收到一条消息时,它可能看起来像这样,带有 HATEOAS 样式的链接:

{
  _links: {
    message: {
      rel: 'message',
      href: 'https://my-server.com/push/<messageId>'
    }
  }
}

客户端然后从 URI 转到GET消息有效负载,此时服务器知道它已被传递并可以相应地更新。获取有效负载也会将其删除。

如果 GCM 重新传递不够健壮,这也意味着客户端可以选择手动获取所有未决消息,例如,当网络连接在离线后恢复时,通过具有返回给定 ANDROID_ID 或类似的所有消息的端点。如果稍后传递 GCM 消息,客户端将获得该消息中 URI 的 404 并将其视为无操作,即消息已处理。

如果这太过分了,一种仅实现服务器对消息传递的感知的轻量级方法是使用一个端点来简单地 ACK 接收具有给定 ID 的消息,例如

POST https://my-server.com/push/notifyReceived

{
  messageId: <messageId>
}
于 2017-03-30T12:34:39.267 回答