实施锁定&在编辑时解锁文档

时间:2011-09-23 12:48:04

标签: javascript ajax locking onunload

情况如下:

我有一个基于网络的故障单应用程序,多个用户。

可能发生的一个问题(并且在我正在替换的旧版本中发生)是user1打开故障单,编辑它并保存它。但是当他正在编辑它时,user2也打开并保存了勾选的内容。 user2所做的更改将被user1丢失/覆盖。

为了防止这种情况,我实现了一种锁定机制,它非常简单:

  1. 在打开票证时,PHP脚本会检查现有锁定。
  2. 如果找不到,它会锁定&打开文件。
  3. 在JS中,setTimeout()和XmlHttpRequest调用在10分钟后解锁票证(无问题)。
  4. 我还设置unload事件,以便在关闭/离开窗口/标签时解锁票证
  5. 问题出在第4步:unload事件(&它的朋友beforeunload)不能很好地实现可靠(对于此功能)有任何严肃的意义,它需要是可靠的),许多浏览器并不总是在我想要它被解雇时触发它(如按下后退按钮,按F5,关闭标签等等,这取决于每个浏览器)

    我能想到的唯一选择是使用setTimeout()XmlHttpRequest()调用php脚本来告诉它页面仍处于打开状态。如果此“心跳”监视器失败,我们假设用户离开了故障单并解锁了文档。

    这对我来说似乎非常低效,并且即使是少数用户也很快会向服务器发出许多请求。

    任何人都对如何处理这个问题有了更好的了解?

    它需要在IE8 +和其他现代浏览器(理想情况下,Firefox,Webkit,Opera)中工作。我不关心IE6 / IE7,我们的组织不使用那些)。

3 个答案:

答案 0 :(得分:1)

通过XHR使用心跳ping是可行的方法。根据用例,您可能还希望在用户停止键入字段而不是每x秒后发送它们 - 这将确保页面保持打开状态但不活动状态不会使其保持锁定状态。

如果您在用户停止输入后发送这些XHR,请使用其中一个keydown/up/press事件和一个 debounce / throttle 脚本,仅在发送请求时发送请求用户停止输入例如5秒和每x秒一次(如果用户长时间输入的可能性很大)。

答案 1 :(得分:1)

也许这不是最佳解决方案,但值得研究: websockets
您可以在页面加载时与服务器建立连接,并且当连接失败时(即客户端不响应ping),您可以解锁票证。
使用socket.io之类的东西可以确保这个程序即使在ie8上也能正常工作。

  • 主要优势是您每隔 n 秒不发送请求,但服务器会每隔 n 秒向您发送一次ping操作您不必关心unload/beforeunload事件。如果客户端没有响应ping,请解锁票证。
  • 主要的缺点是你需要一台服务器来处理所有的websocket连接,这几乎可以用任何服务器端语言完成,但它可能比简单的网络更难一点 - 服务(在xhr民意调查的情况下)

答案 2 :(得分:0)

实现ajax心跳或卸载处理程序以自动解锁文档非常棘手。

问题在于,即使您在所有目标浏览器中都支持beforeunload,如果浏览器崩溃或用户入睡,它仍可能无法调用。

了解webdav的工作原理。您在开始编辑之前明确获取锁定,然后显式保存并释放锁定。 其他用户可以看到谁获得了锁,管理员可以释放意外遗留的锁。