今天解決了一個問題,也就是保證賬號登錄狀態下的唯一性,在此分享下思考過程和解決問題的思路吧
首先,明確問題,一個賬號只能同時被一個人登錄
實現很簡單,在服務器記錄用戶的狀態即可,這個我們通過Map把用戶id和登錄狀態進行映射確實可以記錄用戶登錄狀態.但是緊接着問題來了,
第一個問題,我們怎么知道登錄的是哪個用戶?
解決:使用session保存用戶信息即可,繼續延伸出下一個問題,在哪里記錄用戶登錄的狀態?
1:登錄的地方,將用戶狀態設置為登錄
2:注銷的地方,將用戶狀態設置為下線
3:session失效,首先監聽session,當用戶長時間不使用的時候,會觸發監聽函數,拿到用戶信息,將登錄狀態設置為下線
OK,繼續提出問題:我們保存用戶sessionId的Cookie沒有設置生命周期,也就是15分鍾+臨時會話狀態,也就是關閉瀏覽器后馬上會被銷毀,此時session也拿不到了,而這個時候如果用戶再登錄會發現他登錄不上去,
因為現在出現的情況不在上面兩個會銷毀session情況的任何一個中,此時用戶狀態就仍然為在線狀態.
解決:將cookie和session在攔截器處每次都重置為20分鍾即可
繼續問題:雖然用戶關閉瀏覽器后拿不到之前的session的問題解決了,但是如果用戶手動清空瀏覽器內存呢?此時cookie仍然會被銷毀,我們的用戶在線狀態可能仍然是在線
解決:再添加一個用戶最后操作時間即可,每次經過攔截器都會被刷新,並且最后操作時間與當前時間之間的間隔要大於20分鍾才會被攔截器判斷是否是在線狀態,這樣的話如果用戶在登錄后20分鍾內就算清空瀏覽器內存,也不會因為賬號依然
處於在線狀態而被攔截,而大於20分鍾的話session肯定已經被銷毀了,我們的監聽器也就是第三種情況就起作用了.
所有流程思考時間大概三分鍾便搞定了
最后,如果你的項目是分布式的,只需要做好Session共享以及Cookie跨域,並將用戶Id與登陸狀態的映射放到Redis中即可.
代碼如圖: