2012-01-16 48 views
1

這是很容易建立一個Ajax應用程序,它會檢查所有響應,以確保它們不表示會話到期,如果會話已過期自動友好註銷用戶「您的會話超時由於活動」錯誤信息。如何在Ajax應用程序中暫停設備時處理會話超時?

但在Ajax應用程序的一個普遍的現象是:

  1. 用戶已經登錄,愉快地使用應用程序,以建立HTTP會話檢索通過HTTP數據
  2. 用戶關閉筆記本
  3. 主機超時N分鐘後,HTTP會話
  4. 用戶重新打開筆記本電腦以後。 Ajax應用程序看起來很活躍。他們點擊這些都很好,因爲應用讓他們看到他們已經加載的東西。
  5. 然後,他們點擊一些需要加載數據的數據,並且數據返回,指示會話過期
  6. Ajax應用程序將它們踢出並說「您的會話由於不活動而超時」。

這對用戶來說確實很奇怪,因爲他們的不是從他們的角度來看並不活躍。

現在,有一種可能性是在客戶端使用setTimeout()定期(如果會話超時時間爲30分鐘,每15分鐘一次)觸發一個請求,讓主機詢問剩餘的時間在會議中。這種定期檢查是很好的,因爲它可以讓你在接近超時的時候向他們發出警告,例如, 「除非你有所作爲,否則你會在1分鐘內超時」。

但是,當用戶的機器暫停時沒有幫助。這是因爲根據我在許多不同瀏覽器中的所有測試,setTimeout時間適用於流逝的運行時間,而不是實時流逝的時間。也就是說,如果你調用setTimeout(「alert('hi')」,2 * 60 * 1000);然後暫停您的機器10秒後,等待5分鐘,並重新啓動機器,你必須等待110秒以上,直到你得到警報(我一直沒能找到的這種行爲最終文件,但它是一個顯而易見的事實)。這意味着您的期限檢查可能在用戶的機器恢復後不會發生。

我的解決方案是,而不是根據一個long setTimeout進行定期檢查,而是執行一個簡短的setTimeout(比如說,每5秒),並檢查自上次檢查後使用新Date( ).getTime()獲取實際的時鐘時間。這樣我總是檢查真實的時鐘,而不是客戶端在零到15分鐘之間等待,然後才意識到它在暫停後超時,最多等待約5秒(加上http響應時間)以查明。

但是我不喜歡這個解決方案,因爲它依賴於頻繁的定時器中斷基礎。 有沒有更聰明的方法來處理這個問題?

回答

1

有了很大的網站,如Facebook,它有豐富的互動更新,你會發現,有各種不同機制的組合。我猜他們是在API請求和推送請求上進行驗證(因爲有人曾告訴我他們除了使用ajax之外還使用推送)

超時:要考慮的一件事是,如果您將會話數據存儲在一個cookie,該cookie過期與不再登錄相同。由於cookie是一些散列值,例如用戶ID或時間戳,因此很容易發現在第一次調用API時會話不再有效。

長輪詢:如果一個站點使用長輪詢,其中無限期打開連接以等待來自Web服務器的響應,則關閉計算機將終止該連接。但是,如果他們只是通過setInterval函數調用定期進行ajax輪詢,那麼Web服務器會根據哈希cookie中的時間戳自動知道用戶是否應該獲取數據作爲回報,假設存在一個要檢查。這些是在標題中發送的事物的類型。

某些服務實際上更新數據庫字段,該數據庫字段存儲上次活動的時間戳,並在過了一段時間後過期。這是一種不太有效的方式,因爲它跟蹤狀態。

網站的確有很多方法可以完成這些功能。

+0

長輪詢將可能是一個很好的解決方案,除此之外的一些領域,但我們使用的網絡服務器不支持它... – jlarson

+0

我不認爲任何傳統的網絡服務器真的支持長輪詢還沒有..像node.js這樣的東西可能會更好。如果我是你,我只是在一段時間內驗證cookie。我最近看到一個應用程序,他們做了一個ajax ping函數,基本上每分鐘驗證一次loggedInCookie。它的作用就像一種魅力。 – Kristian