2011-09-23 65 views
3

這裏的情況:在編輯時實現鎖定和解鎖文檔

我有一個基於網絡的票務應用程序,多個用戶。

可能發生的一個問題(和確實發生在我要替換的舊版本中)是user1打開一張票,編輯它並保存它。但是當他編輯它時,user2也打開並保存了勾號。 user2所做的更改將被user1丟失/覆蓋。

爲了防止這一點,我實現了一個鎖定機制,這是相當簡單:

  1. 在開罰單的PHP腳本檢查現有的鎖。
  2. 如果沒有找到,則鎖定&打開文檔。
  3. 在JS中,setTimeout()和一個XmlHttpRequest調用在10分鐘後解鎖票證(無需工作)。
  4. 我還設置一個unload事件解鎖票收盤時/從窗口/標籤移開

問題坐落在步驟4:unload事件(&它的朋友beforeunload)只是沒有按」 (這個功能具有任何嚴肅的意義,它需要可靠),但許多瀏覽器並不總是在我想讓它被觸發的時候觸發它(像按下後退按鈕,點擊F5,關閉標籤等,這根據瀏覽器而變化)

我能想出的唯一選擇是使用setTimeout()XmlHttpRequest()調用php腳本來告訴它頁面仍然打開。如果此「心跳」監視器失敗,我們假定用戶離開票證並解鎖文檔。

這對我來說似乎非常低效,並且很快就會導致很多用戶對服務器的請求。

任何人如何處理這個問題有更好的主意?它需要在IE8 +和其他現代瀏覽器(理想情況下,Firefox,Webkit,Opera)中工作。我不在乎IE6/IE7,我們的組織不使用這些)。

回答

1

通過XHR使用心跳ping是一種可行的方式。根據使用情況,您可能還希望在用戶停止輸入字段而不是每隔x秒輸入一次,這樣可以確保頁面保持打開狀態,但無效狀態不會保持鎖定狀態。

如果用戶停止打字後發送這些XHR時,使用keydown/up/press事件之一和去抖/油門腳本發送只有當用戶停止輸入例如請求5秒和每x秒一次(以防萬一用戶長時間打字)。

+1

謝謝,我實現了這一點,它已經比卸載到目前爲止好得多。 – Carpetsmoker

1

也許這不是最好的解決方案,但它值得研究它:websockets
您可以在加載頁面時與服務器建立連接,並在連接失敗時(即客戶端不響應ping),您可以解鎖票證。
使用像socket.io這樣的東西可以確保您的程序即使在ie8上也能正常工作。

  • 主要優勢是,你不發送請求每ñ秒,但服務器向您發送的ping每ñ秒,你不必在意unload/beforeunload事件。如果客戶端不響應ping,請解鎖票證。
  • 主要的缺點是你需要一個服務器來處理你的所有websocket連接,這可以用幾乎所有的服務器端語言來完成,但它可能比簡單的web服務要困難一些xhr polling)
+0

我(簡單地)想過這個。兩個問題:只有最新的瀏覽器支持(而不是IE8甚至IE9,這是一個要求),它是一種非常新的技術,並沒有很好的測試或理解(HTML/Javascript /網絡歷史告訴我們一些有關這方面的事情。特別是安全方面)。 – Carpetsmoker

+0

安全方面,你是對的,它肯定有安全漏洞,但從兼容性的角度來看,正如我在帖子中所說的,你可以使用socket.io。我在一個項目中使用它,它使用了多種回退機制,以便爲沒有websocket支持的瀏覽器保持相同的api和功能。 –

+0

對不起,我完全錯過了它在IE8上的工作,並被他們無法讀取的網頁關閉:o – Carpetsmoker

0

實現ajax心跳或卸載處理程序來自動解鎖文檔非常棘手。

問題是,即使您在所有目標瀏覽器中都支持beforeunload,但如果瀏覽器崩潰或用戶入睡,它仍可能不會被調用。

看看webdav是如何工作的。在開始編輯之前,您明確地獲取鎖定,然後明確保存並釋放鎖定。 其他用戶可以看到誰獲得了鎖,管理員可以釋放意外遺留的鎖。