【问题标题】:Google App Engine Channels API and sending heartbeat signals from clientGoogle App Engine Channels API 和从客户端发送心跳信号
【发布时间】:2013-04-11 12:37:38
【问题描述】:

从事 GAE 项目,我们的一个要求是我们希望能够及时确定用户是否离开了应用程序。目前我们有这个工作,但不可靠,所以我正在研究替代方案。

我们现在这样做的方式是我们有一个函数设置在 JS 中运行,该函数使用 AJAX 调用向 GAE 应用程序发送心跳信号。这工作相对较好,但会产生大量流量和 CPU 使用率。如果我们在几分钟内没有听到客户的心跳,我们确定他们已经离开了应用程序。我们还连接了卸载函数以发送部分消息,再次通过 AJAX 调用。这效果不太好,但大多数时候根本不行。

我们也在使用 Channels API。我注意到的一件事是,当我们的应用程序使用开放通道时,客户端似乎也在以调用http://talkgadget.google.com/talkgadget/dch/bind 的形式发送心跳信号。我相信这是在客户端打开频道时加载的 iFrame 和/或 JS 发生的。

我的问题是,我在服务器端的应用程序能否连接到这些对http://talkgadget.google.com/talkgadget/dch/bind 的调用并将其用作心跳信号?有没有更好的方法来检测客户端是否仍然连接,即使他们没有在客户端主动做任何事情?

【问题讨论】:

  • 您同时打开了多少个频道?您需要多快知道有人离开了?您多久向客户发送一次消息?
  • 哦,客户端通常是沉默的,还是除了心跳(即聊天消息)之外,它们是否与服务器进行任何通信?
  • 每个客户端打开一个通道。目前并发用户的数量很少,但假设我们会为 100 个或更多的客户拍摄。客户端确实会向服务器发送一些消息,但不能保证频率。
  • 另外,我想我现在更好奇,如果我们的应用程序能够以某种方式“挂钩”或以其他方式在服务器端检测到这些对talkgadget绑定函数或其他一些文档的调用机制。
  • App Engine 团队承诺会添加一个在线状态功能,该功能会在客户端关闭频道时通知您,但目前无法连接到talkgadget。但莫伊什是专家,也许他会对这个问题发表评论。

标签: google-app-engine heartbeat channel-api


【解决方案1】:

Google 已添加此功能:

https://developers.google.com/appengine/docs/java/channel/overview

跟踪客户端连接和断开

应用程序可以注册以在客户端连接到或 与频道断开连接。

您可以在 appengine-web.xml 中启用此入站服务:

【讨论】:

    【解决方案2】:

    目前,通道 API 会预先向您收取通道将消耗两个小时的所有 CPU 时间,因此向死通道发送消息可能比向服务器发送一堆心跳消息更便宜。

    https://groups.google.com/d/msg/google-appengine/sfPTgfbLR0M/yctHe4uU824J

    我会尝试将“请确认”参数附加到每 N 条消息(交错以避免每个客户端确认单个消息)。如果忽略其中 2 个,则将频道静音,直到您收到该客户端的消息。

    【讨论】:

      【解决方案3】:

      您目前无法使用 Channel API 来确定用户是否仍然在线。您目前的最佳选择取决于用户下线后立即了解的重要性。

      如果您只是想知道他们处于离线状态以便停止发送消息,或者立即知道它们并不重要,您可以简单地在常规交互中搭载 ping。每当您向客户端发送更新并且您有一段时间没有收到他们的任何消息时,请使用“ping 请求”标记该消息,并让客户端在收到此类标记的消息时发送 HTTP ping。这样,您在向他们发送消息后不久就会知道他们已经消失了。您也不会产生很多额外的开销,因为他们只需要在您没有从他们那里听到任何其他信息时发送明确的 ping。

      如果您预计会长时间不活动,并且及时知道他们何时下线很重要,那么您必须按照您的建议让他们按计划发送 ping。您仍然可以使用在其他请求上捎带 ping 的技巧来最小化它们,并且您应该在可以管理的范围内设置 ping 之间的间隔,以减少负载。

      【讨论】:

        【解决方案4】:

        对于您将客户端“挂钩”到服务器的核心问题,我没有很好的解决方案。但我确实对您当前的周期性 ping 的“流量和 CPU 使用率”问题有一个有趣的想法。

        我假设您有一个预定义的心跳间隔时间,比如 1 分钟。因此,如果有 120 个客户端,您的服务器将以平均每秒 2 次的速度处理心跳。如果其中一半是“空闲客户”,那就不好了。

        假设客户端已经空闲了 15 分钟。此客户端浏览器是否仍需要以 1 分钟的恒定预定义间隔发送心跳?为什么不让它可变呢?

        我的建议很简单:根据客户的活动水平改变心跳。

        当客户端处于“活动状态”时,心跳以每分钟 1 次的速度工作。当客户端“不活动”超过 5 分钟时,心跳率会减慢到 50%(每 2 分钟一次)。再过 10 分钟,心跳率又下降 50%(每 4 分钟 1 次)...在某个阈值点,将客户端视为“未连接”。

        在这种方法中,“空闲客户端”不会因为频繁的心跳而困扰服务器,让您的应用服务器专注于“活动客户端”。

        有很多 javascript 要做,但如果您在流量和 CPU 使用方面遇到问题,可能值得 :-)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-05
          • 2013-06-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-21
          • 1970-01-01
          相关资源
          最近更新 更多