5

我有某种聊天/论坛应用程序,它使用 jquery ajax 使用定期轮询(每 15 秒)检查新消息。我想知道我是否可以通过加载几个相同的浏览器实例来解决用户试图变得“有趣”的问题,这些实例有很多选项卡,都指向同一个应用程序。每个选项卡都在发送一个 ajax 请求,如果多个用户开始做同样的事情,这可能会导致服务器溢出。

我确实将会话以及上次访问时间和 IP 地址存储在一个表中,只要用户不使用相同的浏览器,它就可以正常工作。我可以存储使用 ajax POST 或 GET 请求发送的唯一标识符,但是如果常规(非滥用)用户刷新他的页面,这会产生问题,然后会创建一个新的标识符。

这还不是一个真正的问题,但最好在有人想到像这样滥用系统之前抓住它:) 知道如何做到这一点吗?

4

4 回答 4

2

一种选择可能是像这样获取数据:

  • 您的脚本正在准备轮询数据。在执行请求之前,写入(使用LocalStorage)一个表示您将要获取数据的值。localStorage.setItem("last-request-timestamp", new Date().getTime());
  • 轮询数据。你得到一个结果。将该结果写入 localStorage:localStorage.setItem("latest-messages", ajax_result);
  • 通过检查是否localStorage.getItem("last-request-timestamp")超过 15 秒前来检查页面是否准备轮询数据。如果是,请转到步骤 1。如果不是,请等待 15 秒并再次检查。
  • 无论当前页面是否轮询数据,检查latest-messages变量并更新页面。

其他页面当然会共享 localStorage 数据。如果此时正在获取另一个页面,他们将不会获取数据。如果页面 #1 关闭,其他页面之一将继续获取数据。

我以前没有使用过 LocalStorage,但浏览器支持似乎足够好。您还应该能够将其用作键值数组:localStorage["last-request-timestamp"].

您只能将字符串存储在 localStorage 中,但您当然可以将其序列化为 JSON。

于 2012-07-12T16:29:50.983 回答
0

不确定它在javascript中是否可行。您可以检查选项卡是否处于活动状态。并且只在活动选项卡上执行 ajax?

于 2012-07-12T00:48:09.863 回答
0

为什么不在问题上抛出 Memcached/Redis 之类的东西呢?以 10-15 秒的生命周期缓存响应,并尽可能避免处理。

于 2012-07-12T17:12:09.167 回答
0

我有类似的问题。现在我强制所有用户登录(这意味着我有他们的电子邮件)。我还设置了每个帐户的连接限制和每个连接的请求限制,5 次溢出后我要求用户输入验证码,然后我阻止帐户 30 分钟并发送带有密码恢复链接的电子邮件。这不是一个明确的解决方案,但现在它对我有用。

升级版:

最简单的方法是使用 cookie 或会话存储。我使用饼干。算法很简单:

  1. 用户在 Web 上登录。
  2. 检查该用户是否有任何打开的会话,打开,然后删除另一个会话或触发异常或切换到该会话,您已经决定了自己想要的行为。
  3. 为用户创建会话 ID 并将其存储在数据库中。
  4. 为特定用户增加会话计数器字段以检测打开的会话,因此现在使用一个浏览器或多个浏览器都没有关系。
  5. 更新最后一个访问标记(我使用microtime(true) + $delay和 mysql decimal(14,4))。发送给用户
  6. 发送 id 给客户

在每个请求上:

  1. 通过 $_COOKIE 中传递的 id 搜索会话。
  2. 检查最后一个访问标记。如果它小于则microtime(true)意味着客户端发送请求频繁,所以决定自己做什么,增加标记,例如microtime(true) + $delay + $penalty或丢弃整个会话或触发错误。行为取决于您的应用程序。
于 2012-07-11T23:30:34.247 回答