# 在线用户管理
Heimdall 对所有在线用户信息进行统一缓存管理。针对在线用户,Heimdall 框架实现了:
- 查看在线用户列表
- 踢出在线用户
- 过期自动清除机制
# 在线用户列表
针对不同缓存类型,主要实现方法如下:
/**
* 获取所有活动Session,也即是在线用户
*
* @return the active sessions
*/
Collection<SimpleSession> getActiveSessions();
/**
* 分页获取所有活动Session,也即是在线用户
* <p>
* 注意:仅Redis缓存可用
* @param pageNo 页码
* @param pageSize 每页数量
* @return the active sessions
*/
default Page<SimpleSession> getActiveSessions(int pageNo, int pageSize) {
System.out.println("======default getActiveSessions with page and size");
return null;
}
对于 Caffeine 缓存,在线用户列表不支持分页查看,所有用户信息以 Map 格式进行缓存。
Map<String,SimpleSession> sessionCache;
对于 Redis 缓存,系统分别实现了用户缓存、Session 缓存、在线 SessionID。参见: 系统缓存实现
# 获取在线用户列表信息
- Caffeine 缓存
//注入认证管理器
private final AuthenticationManager authenticationManager;
/**
* 内存缓存只支持一次全部获取
*/
@GetMapping
public Collection<SimpleSession>> list() {
return authenticationManager.getActiveSessions();
}
- Redis 缓存
//注入认证管理器
private final AuthenticationManager authenticationManager;
/**
* Redis 缓存下支持分页获取
* 需要注意:返回的 Session 中,会因为清理缓存的时差有个别为空的情况,
* 使用之前需要对数据是否为空进行判断
*/
@GetMapping
public Page<SimpleSession>> listPage(PagerVO page) {
return authenticationManager.getActiveSessions(page.getPage(), page.getSize());
}
# 踢出在线用户
踢出在线用户,也就是作废已认证用户的认证凭据,作废后,用户访问系统必须重新登录认证。 可通过 principal 或者 SessinId两种方式踢出用户,如下所示:
//注入认证管理器
private final AuthenticationManager authenticationManager;
/**
* 通过 SessionId踢出用户
*
*/
@DeleteMapping
public Boolean kickOutSid(@RequestParam String sessionId) {
return authenticationManager.kickOutSession(sessionId);
}
/**
* 通过 Principal 踢出用户
*
*/
@DeleteMapping
public Boolean kickOutPrincipal(@RequestParam String principal) {
return authenticationManager.kickOutPrincipal(sessionId);
}
# 自动清除机制
Heimdall 框架会通过定时任务定期检查过期 Session 并且清理。
对于 Caffeine 缓存来说,可以设置缓存过期参数:expireAfterAccess来实现自动清理。
对于 Redis缓存, 设置了Session Key 的 TTL 过期时间,redis 会在过期之后自动将 Session Key删除。同时,redis 中还缓存了用户信息 Hash 和 SessionID 分页信息 ZSet,这两个缓存中的数据,通过 Redis 事件通知机制进行清理,当 Session 被 Redis 清除后,同步将 Hash 和 Zset 中对应的 Session 数据也清除。
由于系统出错或者其他问题,造成的脏数据,最后都会由定时清理任务统一进行判断和清除。 定时清理任务的配置方法如下:
/**
* Session 自动清理 定时任务
*
*/
@Bean
public DefaultInvalidSessionClearScheduler defaultInvalidSessionClearScheduler(SessionDAO sessionDAO) {
log.warn("初始化 Session 自动清理任务");
return new DefaultInvalidSessionClearScheduler(sessionDAO);
}