情况如下:
我有一个基于网络的故障单应用程序,多个用户。
可能发生的一个问题(并且在我正在替换的旧版本中发生)是user1打开故障单,编辑它并保存它。但是当他正在编辑它时,user2也打开并保存了勾选的内容。 user2所做的更改将被user1丢失/覆盖。
为了防止这种情况,我实现了一种锁定机制,它非常简单:
setTimeout()
和XmlHttpRequest调用在10分钟后解锁票证(无问题)。unload
事件,以便在关闭/离开窗口/标签时解锁票证 问题出在第4步:unload
事件(&它的朋友beforeunload
)不能很好地实现可靠(对于此功能)有任何严肃的意义,它需要是可靠的),许多浏览器并不总是在我想要它被解雇时触发它(如按下后退按钮,按F5,关闭标签等等,这取决于每个浏览器)
我能想到的唯一选择是使用setTimeout()
和XmlHttpRequest()
调用php脚本来告诉它页面仍处于打开状态。如果此“心跳”监视器失败,我们假设用户离开了故障单并解锁了文档。
这对我来说似乎非常低效,并且即使是少数用户也很快会向服务器发出许多请求。
任何人都对如何处理这个问题有了更好的了解?
它需要在IE8 +和其他现代浏览器(理想情况下,Firefox,Webkit,Opera)中工作。我不关心IE6 / IE7,我们的组织不使用那些)。
答案 0 :(得分:1)
通过XHR使用心跳ping是可行的方法。根据用例,您可能还希望在用户停止键入字段而不是每x秒后发送它们 - 这将确保页面保持打开状态但不活动状态不会使其保持锁定状态。
如果您在用户停止输入后发送这些XHR,请使用其中一个keydown/up/press
事件和一个 debounce / throttle 脚本,仅在发送请求时发送请求用户停止输入例如5秒和每x秒一次(如果用户长时间输入的可能性很大)。
答案 1 :(得分:1)
也许这不是最佳解决方案,但值得研究: websockets 。
您可以在页面加载时与服务器建立连接,并且当连接失败时(即客户端不响应ping),您可以解锁票证。
使用socket.io之类的东西可以确保这个程序即使在ie8上也能正常工作。
unload/beforeunload
事件。如果客户端没有响应ping,请解锁票证。答案 2 :(得分:0)
实现ajax心跳或卸载处理程序以自动解锁文档非常棘手。
问题在于,即使您在所有目标浏览器中都支持beforeunload,如果浏览器崩溃或用户入睡,它仍可能无法调用。
了解webdav的工作原理。您在开始编辑之前明确获取锁定,然后显式保存并释放锁定。 其他用户可以看到谁获得了锁,管理员可以释放意外遗留的锁。