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

Implement locking & unlocking a document while editing

本文关键字:解锁 文档 编辑 锁定 实现      更新时间:2023-09-26

情况如下:

我有一个基于web的票务应用程序,多个用户。

可能发生的一个问题(在我要替换的旧版本中确实会发生)是user1打开一个票据,编辑它并保存它。但是,当他在编辑它时,user2也打开并保存了tick。user2所做的更改将被user1丢失/覆盖。 为了防止这种情况,我实现了一个锁定机制,它相当简单:
    在打开票证时,PHP脚本检查是否存在锁。
  1. 如果没有找到,它会锁定&
  2. 在JS中,setTimeout()和XmlHttpRequest调用在10分钟后解锁票据(工作w/o问题)。
  3. 我还设置了一个unload事件来解锁票时关闭/离开窗口/选项卡

问题出现在步骤4:unload事件(&它的朋友beforeunload)只是不能很好地实现这个可靠(这个功能有任何严重的意义,它需要是可靠的),许多浏览器并不总是火它当我想要它被解雇(如按后退键,按F5,关闭选项卡等。这因浏览器而异)

我能想到的唯一替代方法是使用setTimeout()XmlHttpRequest()调用php脚本来告诉它页面仍然打开。如果这个"心跳"监控器失败,我们假设用户离开了票据并解锁了文档。

对我来说,这似乎非常低效,并且很快导致即使只有几个用户也会向服务器发出许多请求。

谁有更好的主意如何处理这个?

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

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

如果你在用户停止打字后发送这些xhr,使用keydown/up/press事件之一和debounce/throttle脚本只在用户停止打字时发送请求,例如5秒和每x秒一次(如果用户很可能会长时间打字)。

也许这不是最好的解决方案,但值得研究一下:websockets
您可以在页面加载时与服务器建立连接,当连接失败时(即客户端没有响应ping),您可以解锁票据。
使用类似socket的东西。IO确保这个过程即使在ie8上也能工作。

  • 的主要优点是您不需要每n秒发送一个请求,但是服务器每n秒发送一个ping,并且您不必关心unload/beforeunload事件。如果客户端没有响应ping,解锁票据。
  • 的主要缺点是需要一个服务器来处理所有的websocket连接,这几乎可以在任何服务器端语言中完成,但它可能比简单的web服务(在xhr轮询的情况下)更难一点

实现ajax心跳或卸载处理程序来自动解锁文档是很棘手的。

你的问题是,即使你在你的目标浏览器中支持beforeunload,如果浏览器崩溃或用户睡着了,它仍然可能不会被调用。

看看webdav是如何工作的。在开始编辑之前显式地获取锁,然后显式地保存并释放锁。其他用户可以看到谁获得了锁,管理员可以释放意外留下的锁。