Реализовать блокировку и разблокировку документа при редактировании - PullRequest
3 голосов
/ 23 сентября 2011

Вот ситуация:

У меня есть веб-приложение для заявок, несколько пользователей.

Одна проблема, которая может возникнуть (а действительно возникает в старой версииЯ заменяю) это то, что user1 открывает тикет, редактирует и сохраняет его.Но пока он редактировал его, user2 также открывал и сохранял галочку.Изменения, внесенные пользователем 2, будут потеряны / перезаписаны пользователем 1.

Чтобы предотвратить это, я реализовал механизм блокировки, это довольно просто:

  1. При открытии заявки PHP-скрипт проверяет наличиеблокирует.
  2. Если он не находит, он блокирует и открывает документ.
  3. В JS setTimeout() и вызов XmlHttpRequest для разблокирования заявки через 10 минут (работает безo проблемы).
  4. Я также установил событие unload, чтобы разблокировать билет при закрытии / удалении от окна / вкладки

Проблема сидитна шаге 4: событие unload (и его друг beforeunload) просто не работает достаточно хорошо, чтобы надежно реализовать (чтобы эта функция имела какое-либо серьезное значение, она должна быть надежной)многие браузеры не всегда запускают его, когда я хочу, чтобы он запускался (например, нажатие кнопки назад, нажатие клавиши F5, закрытие вкладки и т. д. Это зависит от браузера)

Единственная альтернатива, которую я могу придуматьиспользует setTimeout() и XmlHttpRequest() вызов PHP-скриптаЧтобы сказать это, страница все еще открыта.Если этот монитор «сердцебиения» не работает, мы предполагаем, что пользователь отошел от заявки и разблокировал документ.

Мне это кажется ужасно неэффективным и быстро приводит к многочисленным запросам к серверу даже с несколькими пользователями.

Кто-нибудь получил лучшее представление о том, как с этим справиться?

Он должен работать в IE8 + и других современных браузерах (в идеале, Firefox, Webkit, Opera).Меня не волнует IE6 / IE7, наша организация их не использует).

Ответы [ 3 ]

1 голос
/ 23 сентября 2011

Возможно, это не лучшее решение, но его стоит рассмотреть: websockets .
Вы можете установить соединение с сервером при загрузке страницы и при сбое соединения (т. Е. Клиент неответьте на пинг), вы можете разблокировать билет.
Использование чего-то вроде socket.io гарантирует, что эта процедура будет работать даже на ie8.

  • Основное преимущество заключается в том, что вы не отправляете запрос каждые n секунд, но сервер отправляет вам пинг каждые n * 1015.* секунд, и вам не нужно заботиться о unload/beforeunload событиях.Если клиент не отвечает на эхо-запрос, разблокируйте тикет.
  • Основной недостаток заключается в том, что вам необходим сервер для обработки всех ваших соединений через веб-сокет, что может быть сделано практически в любомсерверный язык, но он может быть немного сложнее, чем простой веб-сервис (в случае xhr-опроса)
1 голос
/ 23 сентября 2011

Использование сердцебиения через XHR - путь. В зависимости от варианта использования вы также можете отправлять их после того, как пользователь перестал вводить данные в поле вместо каждых x секунд - это обеспечит сохранение открытой страницы, но неактивной, не заблокирует ее.

Если вы отправляете эти XHR после того, как пользователь перестал печатать, используйте одно из событий keydown/up/press и сценарий debounce / throttle , чтобы отправлять запрос только тогда, когда пользователь перестает печатать например 5 секунд и один раз в x секунд (если этого достаточно, пользователь будет долго печатать).

0 голосов
/ 23 сентября 2011

Реализация ajax heartbeats или обработчиков выгрузки для автоматической разблокировки документа является сложной задачей.

Проблема в том, что даже если у вас есть поддержка beforeunload во всех целевых браузерах, она все равно может не вызываться, если браузерпадает или пользователь засыпает.

Посмотрите, как работает webdav.Вы явно получаете блокировку перед началом редактирования, затем вы явно сохраняете и снимаете блокировку.Другие пользователи могут видеть, кто получил блокировку, и администраторы могут снимать блокировки, которые были оставлены случайно.

...