实现思路
数据库中添加用户是否登录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>