Web 服务内的 GCM 应用程序服务器

Posted

技术标签:

【中文标题】Web 服务内的 GCM 应用程序服务器【英文标题】:GCM Application server inside web service 【发布时间】:2014-07-04 12:48:57 【问题描述】:

我创建了一个允许用户向其他用户发送消息的 android 应用程序。为了实现这一点,我使用了GCM。因此,用户可以使用 Web 服务(使用 Web API 框架开发)发送消息,该服务将消息保存在远程数据库(SQL Server)上,并联系 GCM 服务器以将 GCM 消息传递给收件人。

可能会发生未接收到 GCM 的消息,例如因为 GCM 服务器暂时不可用。所以谷歌建议尝试使用指数退避来重新发送。这对我的架构来说是一个问题,因为我从另一个 WS 内部调用 GCM(我创建的那个,用于用户向其他用户发送消息)。如果我尝试使用指数回退,我的外部 WS 应该是活动的,因为 GCM 返回一个有效的响应。

因此,从另一个 Web 服务内部调用 GCM Web 服务似乎不是一件好事。这是正确的吗?你能给我什么建议吗?使用 GCM 的 IM 应用程序最常见的架构是什么?

【问题讨论】:

【参考方案1】:

在我看来,您的问题是您用于向 GCM 发送消息的 Web 服务是同步的(至少这是我根据您的问题所假设的)。即,它接收来自您的客户端的请求,向 GCM 服务器发送请求,并在从 GCM 服务器获得响应后向您的客户端返回响应。

我建议您更改架构。您的网络服务应该从您的客户端接收消息,将其存储在您的数据库中并向客户端返回响应。

您的服务器中的一个单独线程应定期唤醒以查看您的数据库中是否有任何待处理的消息,并尝试将它们发送到 GCM 服务器。如果您从 GCM 收到指示您应该稍后重试的错误,您可以使用下次发送尝试的时间戳更新数据库中的消息(并根据指数回退要求设置时间戳)。如果您从 GCM 获得成功的响应,则从您的数据库中删除该消息。

【讨论】:

谢谢@Eran。但是,使用定期唤醒系统不会使我的系统接近即时消息应用程序所要求的实时。 @Joseph82 定期唤醒不一定需要很长时间。它可以每秒唤醒一次以检查是否有任何待处理的消息要发送到 GCM 服务器。如果您想减少延迟,您可以在从客户端获取消息的 Web 服务中执行第一次传递尝试,并且只在单独的线程中进行重试(如果需要)。我认为该解决方案不太优雅,但它仍然有效。 当然@Eran,但安排一个非常高频率的工作我认为这不是一个好主意。 "SQL Agent Job scheduler 本身很轻量,SQL Server 原生支持的最小间隔是 1 分钟。如果你的目标是让你 Job 尽快响应新文件,那么将调度设置为每 1 分钟运行一次。"

以上是关于Web 服务内的 GCM 应用程序服务器的主要内容,如果未能解决你的问题,请参考以下文章

GCM 云服务器可以访问我的应用服务器数据库表吗?

GCM频繁刷新注册id

在 GCM 中发送推送通知时出现未经授权的错误

Android GCM 切换到另一个网络

从 php 推送到 GCM/APN 的最佳实践

Android GCM 一台设备有多个registrationid