實現思路
數據庫中添加用戶是否登錄is_login字段,用來記錄用戶的登錄狀態,假設1表示在線;0表示未在線,則需要進行控制:
1)當用戶登錄成功時,設置用戶登錄狀態為1
2)當用戶退出登錄時,設置用戶登錄狀態為0
3)當session失效時,設置對應的用戶的登錄狀態為0
實現方法
1、更改數據庫字段,編寫登錄狀態更新函數
添加字段后,編寫狀態更新函數
/** 更改用戶登錄狀態 */ void updateLoginStatus(@Param("userId") String userId, @Param("islogin") Integer islogin);
<update id="updateLoginStatus"> UPDATE `user` SET `islogin`=#{islogin} WHERE id = #{userId} </update>
2、自定義SessionLinstener,重寫監聽函數
自定義一個類ShiroSessionLinstener,繼承SessionLinstenerAdapter類,同時重寫監聽函數
1)session創建時,輸出sessionId,不進行任何操作
2)session停止時,輸入sessionId和session存儲的用戶Id,不進行任何操作
3)session失效時,輸入sessionId,重置對應的用戶的登錄狀態為0
public class ShiroSessionListener extends SessionListenerAdapter { @Resource private UserService userService; // session創建 @Override public void onStart(Session session) { super.onStart(session); System.out.println("session創建,sessionId:" + session.getId()); } // session停止 @Override public void onStop(Session session) { System.out.println("session停止,sessionId:" + session.getId() +",用戶id:" + session.getAttribute("loginUserId")); } // session失效 @Override public void onExpiration(Session session) { // 重置登錄狀態 userService.updateLoginStatus(session.getAttribute("loginUserId").toString(), LoginStatusEnum.NOT_LOGIN.getCode()); System.out.println("session失效,sessionId:" + session.getId() +",用戶id:" + session.getAttribute("loginUserId")); } }
3、配置session監聽及屬性(均通過SessionManager進行配置)
1)使用setGlobalSessionTimeout(1800000L)設置session的過期時間為30分鍾(可自定義)
2)使用setSessionValidationSchedulerEnabled(true)開啟session檢查
3)使用setSessionValidationInterval(15 * 60 * 1000L)設置檢查間隔為15分鍾
4)設置監聽類為第2步自定義的類
Collection<SessionListener> listeners = new ArrayList<>(); listeners.add(shiroSessionListener()); sessionManager.setSessionListeners(listeners);
最后不要忘記把SessionManager配置到ShiroConfig中
4、編寫查詢函數查詢在線人數
/** 獲取在線人數 */ Integer getLoginCount();
<select id="getLoginCount" resultType="java.lang.Integer">
SELECT count(1) FROM `user` WHERE `is_login` = 1
</select>