尽管框架将大部分操作提供了简易的封装,但在一些特殊场景下,我们仍需要绕过框架,直达数据底层进行一些操作。
1、官方文档
会话查询
https://sa-token.cc/doc.html#/up/search-session
Sa-Token提供以下API助你直接操作会话列表:
// 查询所有已登录的 Token
StpUtil.searchTokenValue(String keyword, int start, int size, boolean sortType);
// 查询所有账号 Session 会话
StpUtil.searchSessionId(String keyword, int start, int size, boolean sortType);
// 查询所有令牌 Session 会话
StpUtil.searchTokenSessionId(String keyword, int start, int size, boolean sortType);
参数详解:
- keyword: 查询关键字,只有包括这个字符串的 token 值才会被查询出来。
- start: 数据开始处索引。
- size: 要获取的数据条数 (值为-1代表一直获取到末尾)。
- sortType: 排序方式(true=正序:先登录的在前,false=反序:后登录的在前)。
2、效果预览
由图中可以看出,我们查询了在线用户的基本登录信息,包括(账号、姓名、部门、登录IP、登录位置、操作系统、登录设备类型、浏览器信息)等信息,还提供了【强退】的功能按钮
3、在线用户查询
public TableInfoVO list(int page, int size) {
// 返回数据对象
List<LoginUserRespVO> list = new ArrayList<>();
// 获取所有登录的用户ids
List<String> logIds = StpUtil.searchSessionId("", 0, -1, false);
// 便利获取登录信息
SaSession session = null;
for (int i = page * size, len = Math.min(size + i, logIds.size()); i < len; i++) {
session = StpUtil.getSessionBySessionId(logIds.get(i));
list.add(session.getModel("user_info", LoginUserRespVO.class));
}
return TableInfoVO.ok(logIds.size(), list);
}
通过 sa-token 提供的会话查询方法,底层是用的 keys 命令,然后根据分页参数,截取我们需要的数据,再根据会话查询登录用户信息
4、用户强退
public RES updateQuitOnline(Long[] ids) {
// 强制下线
for (Long item : ids) {
StpUtil.kickout(item);
}
return RES.success();
}
由前端传回需要强退的用户登录 id,调用 StpUtil.kickout(Object loginId); 方法,即可实现让用户强制下线操作
5、注意事项
由于会话查询底层采用了遍历方式获取数据,当数据量过大时此操作将会比较耗时,有多耗时呢?这里提供一份参考数据:
- 单机模式下:百万会话取出10条 Token 平均耗时 0.255s。
- Redis模式下:百万会话取出10条 Token 平均耗时 3.322s。
请根据业务实际水平合理调用API。
基于活动 Token 的统计方式会比实际情况略有延迟,如果需要精确统计实时在线用户信息建议采用 WebSocket。
如您在阅读中发现不足,欢迎留言!!!