2012-01-16 46 views
1

这是很容易建立一个Ajax应用程序,它会检查所有响应,以确保它们不表示会话到期,如果会话已过期自动友好注销用户“您的会话超时由于活动”错误信息。如何在Ajax应用程序中暂停设备时处理会话超时?

但在Ajax应用程序的一个普遍的现象是:

  1. 用户已经登录,愉快地使用应用程序,以建立HTTP会话检索通过HTTP数据
  2. 用户关闭笔记本
  3. 主机超时N分钟后,HTTP会话
  4. 用户重新打开笔记本电脑以后。 Ajax应用程序看起来很活跃。他们点击这些都很好,因为应用让他们看到他们已经加载的东西。
  5. 然后,他们点击一些需要加载数据的数据,并且数据返回,指示会话过期
  6. Ajax应用程序将它们踢出并说“您的会话由于不活动而超时”。

这对用户来说确实很奇怪,因为他们的不是从他们的角度来看并不活跃。

现在,有一种可能性是在客户端使用setTimeout()定期(如果会话超时时间为30分钟,每15分钟一次)触发一个请求,让主机询问剩余的时间在会议中。这种定期检查是很好的,因为它可以让你在接近超时的时候向他们发出警告,例如, “除非你有所作为,否则你会在1分钟内超时”。

但是,当用户的机器暂停时没有帮助。这是因为根据我在许多不同浏览器中的所有测试,setTimeout时间适用于流逝的运行时间,而不是实时流逝的时间。也就是说,如果你调用setTimeout(“alert('hi')”,2 * 60 * 1000);然后暂停您的机器10秒后,等待5分钟,并重新启动机器,你必须等待110秒以上,直到你得到警报(我一直没能找到的这种行为最终文件,但它是一个显而易见的事实)。这意味着您的期限检查可能在用户的机器恢复后不会发生。

我的解决方案是,而不是根据一个long setTimeout进行定期检查,而是执行一个简短的setTimeout(比如说,每5秒),并检查自上次检查后使用新Date( ).getTime()获取实际的时钟时间。这样我总是检查真实的时钟,而不是客户端在零到15分钟之间等待,然后才意识到它在暂停后超时,最多等待约5秒(加上http响应时间)以查明。

但是我不喜欢这个解决方案,因为它依赖于频繁的定时器中断基础。 有没有更聪明的方法来处理这个问题?

回答

1

有了很大的网站,如Facebook,它有丰富的互动更新,你会发现,有各种不同机制的组合。我猜他们是在API请求和推送请求上进行验证(因为有人曾告诉我他们除了使用ajax之外还使用推送)

超时:要考虑的一件事是,如果您将会话数据存储在一个cookie,该cookie过期与不再登录相同。由于cookie是一些散列值,例如用户ID或时间戳,因此很容易发现在第一次调用API时会话不再有效。

长轮询:如果一个站点使用长轮询,其中无限期打开连接以等待来自Web服务器的响应,则关闭计算机将终止该连接。但是,如果他们只是通过setInterval函数调用定期进行ajax轮询,那么Web服务器会根据哈希cookie中的时间戳自动知道用户是否应该获取数据作为回报,假设存在一个要检查。这些是在标题中发送的事物的类型。

某些服务实际上更新数据库字段,该数据库字段存储上次活动的时间戳,并在过了一段时间后过期。这是一种不太有效的方式,因为它跟踪状态。

网站的确有很多方法可以完成这些功能。

+0

长轮询将可能是一个很好的解决方案,除此之外的一些领域,但我们使用的网络服务器不支持它... – jlarson

+0

我不认为任何传统的网络服务器真的支持长轮询还没有..像node.js这样的东西可能会更好。如果我是你,我只是在一段时间内验证cookie。我最近看到一个应用程序,他们做了一个ajax ping函数,基本上每分钟验证一次loggedInCookie。它的作用就像一种魅力。 – Kristian