Here's the situation:
I have a web-based ticket application, multiple users.
One problem that might occur (and does happen in the old version I'm replacing) is that user1 opens a ticket, edits it, and saves it. But while he was editing it, user2 also opened and saved the ticked. The changes user2 made will be lost/overwritten by user1.
To prevent this I implemented a locking mechanism, it's fairly simply:
setTimeout()
and an XmlHttpRequest call to unlocks the ticket after 10 minutes (works w/o problems).unload
event to unlock the ticket when closing/moving away from the window/tabThe problem sits in step 4: The unload
event (& it's friend beforeunload
) just doesn't work well enough to implement this reliably (for this feature to have any serious meaning, it needs to be reliable), many browsers don't always fire it when I would like it to be fired (Like pressing back button, hitting F5, closing tab, etc. This varies per browser)
The only alternative I can come up with is using a setTimeout()
and XmlHttpRequest()
call to a php script to tell it the page is still open. If this "heartbeat" monitor fails we assume the user moved away from the ticket and unlock the document.
This seems horribly inefficient to me and quickly leads to many requests to the server with even a few users.
Anyone got a better idea on how to handle this?
It needs to work in IE8+ and other modern browsers (ideally, Firefox, Webkit, Opera). I don't care about IE6/IE7, our organization doesn't use those).
Using heartbeat pings via XHR is the way to go. Depending on the use case you might also want to send them after the user stopped typing in a field instead of every x seconds - this would ensure the page being kept open but inactive would not keep it locked.
If you send those XHRs after the user stopped typing, use one of the keydown/up/press
events and a debounce / throttle script to send the request only when the user stops typing for e.g. 5 seconds and one every x seconds (in case it's likely enough the user will be typing for a long time).