处理GAE项目,我们的一个要求就是我们希望能够及时确定用户是否已离开该应用程序。目前我们有这个工作,但是不可靠,所以我正在研究替代方案。
我们现在这样做的方法是,我们有一个函数设置,可以在JS上运行一个间隔,该间隔使用AJAX调用向GAE应用程序发送心跳信号。这种方法效果相对较好,但却产生了大量的流量和CPU使用率。如果我们几分钟没有听到客户的心跳声,我们确定他们已经离开了应用程序。我们还将卸载功能连接起来,再次通过AJAX调用发送部分消息。这样做效果不太好,但大部分时间都没有。
我们也在使用Channels API。我注意到的一件事是我们的应用程序在使用开放频道时,客户端似乎也会以http://talkgadget.google.com/talkgadget/dch/bind的呼叫形式发送心跳信号。我相信这是从在客户端打开频道时加载的iFrame和/或JS发生的。
我的问题是,我的应用程序在服务器端可以与这些http://talkgadget.google.com/talkgadget/dch/bind的调用挂钩,并将其用作心跳信号吗?是否有更好的方法来检测客户端是否仍然连接,即使他们没有在客户端中主动执行任何操作?
答案 0 :(得分:3)
Google已添加此功能:
请参阅https://developers.google.com/appengine/docs/java/channel/overview
跟踪客户端连接和断开连接
当客户连接到或时,应用程序可以注册以通知 断开与频道的连接。
您可以在appengine-web.xml中启用此入站服务:
答案 1 :(得分:1)
目前,渠道API会预先通知您渠道消耗两个小时的所有CPU时间,因此将消息发送到死信道可能比向服务器发送大量心跳消息要便宜。
https://groups.google.com/d/msg/google-appengine/sfPTgfbLR0M/yctHe4uU824J
我要尝试的是在每个第N条消息上附加一个“请确认”参数(交错以避免每个客户端确认一条消息)。如果忽略其中两个,则忽略该频道,直到您收到该客户端的声音。
答案 2 :(得分:1)
您目前无法使用Channel API来确定用户是否仍在线。您现在最好的选择取决于用户下线后立即知道的重要性。
如果您只是想知道他们处于离线状态,那么您可以停止发送消息,或者您不会立即知道这些消息,您可以简单地在常规交互中捎带ping。每当您向客户端发送更新并且您暂时没有收到任何消息时,请使用“ping请求”标记消息,并让客户端在收到此类标记消息时发送HTTP ping。通过这种方式,您可以在发送消息后立即知道它们已经消失。你也没有增加很多额外的开销,因为如果你没有听到任何其他内容,他们只需要发送明确的ping。
如果您预计长时间不活动,并且在离线时及时知道这一点非常重要,那么您必须让他们按照您的建议按计划发送ping。您仍然可以使用ping其他请求的ping技巧来最小化它们,并且您应该设置ping之间的间隔,只要您可以管理,以减少负载。
答案 3 :(得分:1)
我没有一个很好的解决方案来解决将客户端“连接”到服务器的核心问题。但我确实对你目前的定期ping“流量和CPU使用率”问题有了一个有趣的想法。
我假设你有一个预定义的心跳间隔时间,比如1分钟。因此,如果有120个客户端,您的服务器将以平均每秒2次的速度处理心跳。如果其中一半是“空闲客户”,那就不好了。
让我们假设客户已经闲置了15分钟。此客户端浏览器是否仍需要以1分钟的固定预定义间隔发送心跳?为什么不让它变量?
我的提议很简单:根据客户的活动水平改变心跳。
当客户端处于“活动状态”时,心跳以每分钟1次的速度运行。当客户端处于“非活动状态”超过5分钟时,心率降低至50%(每2分钟一次)。再过10分钟,心跳率再下降50%(每4分钟1次)......在某个门槛点,将客户视为“脱钩”。
在这种方法中,“空闲客户端”不会给频繁心跳的服务器带来麻烦,让您的应用服务器专注于“活跃客户端”。
它有很多javascript要做,但如果你遇到流量和CPU使用问题,可能值得: - )