XilongPei / Openparts

MIT License
3 stars 1 forks source link

会话控制器 #63

Open XilongPei opened 6 years ago

XilongPei commented 6 years ago

有时候需要显示当前在线人数、当前在线用户,有时候可能需要强制某个用户下线等;此时就需要获取相应的在线用户并进行一些操作。 http://jinnianshilongnian.iteye.com/blog/2047643

分页获取时,如果是MySQL这种关系数据库存储会话比较好办,如果使用Redis这种数据库可以考虑这样存储: session.id=会话序列化数据
session.ids=会话id Set列表(接着可以使用LLEN获取长度,LRANGE分页获取)
会话创建时(如sessionId=123),那么redis命令如下所示:
SET session.123 "Session序列化数据"
LPUSH session.ids 123
会话删除时(如sessionId=123),那么redis命令如下所示: DEL session.123
LREM session.ids 123
获取总活跃会话: LLEN session.ids
分页获取活跃会话: LRANGE key 0 10 #获取到会话ID
MGET session.1 session.2…… #根据第一条命令获取的会话ID获取会话数据

XilongPei commented 6 years ago

shiro的会话验证调度器SessionValidationScheduler http://blog.csdn.net/zsg88/article/details/73832714 http://jinnianshilongnian.iteye.com/blog/2029717

XilongPei commented 6 years ago

利用Redis的timeout机制自动清理session。

        String uid = getUserId(session);
        if (!StrUtil.isEmpty(uid)) {
            //保存用户会话对应的UID
            try {
                redisDao.add(this.getKey(RedisConstant.SHIRO_SESSION_PRE, session.getId().toString()), timeout, uid.getBytes("UTF-8"));
                //保存在线UID
                redisDao.add(this.getKey(RedisConstant.UID_PRE, uid), timeout, "online".getBytes("UTF-8"));
            } catch (UnsupportedEncodingException ex) {
                logger.error("getBytes error:" + ex.getMessage());
            }
        }
XilongPei commented 6 years ago

在SystemFilter过滤器上做文章,此时做是否被强制退出检查,如果是被强制退出,则forceLogout。 http://wiki.jikexueyuan.com/project/shiro/online-session.html http://jinnianshilongnian.iteye.com/blog/2047643 http://jinnianshilongnian.iteye.com/blog/2028675

@RequiresPermissions("session:*")
@Controller
@RequestMapping("/sessions")
public class SessionController {
    @Autowired
    private SessionDAO sessionDAO;
    @RequestMapping()
    public String list(Model model) {
        Collection<Session> sessions =  sessionDAO.getActiveSessions();
        model.addAttribute("sessions", sessions);
        model.addAttribute("sesessionCount", sessions.size());
        return "sessions/list";
    }
    @RequestMapping("/{sessionId}/forceLogout")
    public String forceLogout(@PathVariable("sessionId") String sessionId, 
        RedirectAttributes redirectAttributes) {
        try {
            Session session = sessionDAO.readSession(sessionId);
            if(session != null) {
                session.setAttribute(
                    Constants.SESSION_FORCE_LOGOUT_KEY, Boolean.TRUE);
            }
        } catch (Exception e) {/*ignore*/}
        redirectAttributes.addFlashAttribute("msg", "强制退出成功!");
        return "redirect:/sessions";
    }
}
XilongPei commented 6 years ago

如何使用RedisTemplate访问Redis数据结构 https://github.com/XilongPei/Openparts/issues/63 征服 Redis + Jedis + Spring (三)—— 列表操作 http://snowolf.iteye.com/blog/1824868