package com.javaweb.framework.shiro.session; import java.io.Serializable; import java.util.Date; import org.apache.shiro.session.Session; import org.apache.shiro.session.UnknownSessionException; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import com.javaweb.common.enums.OnlineStatus; import com.javaweb.framework.manager.AsyncManager; import com.javaweb.framework.manager.factory.AsyncFactory; import com.javaweb.framework.shiro.service.SysShiroService; /** * 针对自定义的ShiroSession的db操作 * * @author ruoyi */ public class OnlineSessionDAO extends EnterpriseCacheSessionDAO { /** * 同步session到数据库的周期 单位为毫秒(默认1分钟) */ @Value("${shiro.session.dbSyncPeriod}") private int dbSyncPeriod; /** * 上次同步数据库的时间戳 */ private static final String LAST_SYNC_DB_TIMESTAMP = OnlineSessionDAO.class.getName() + "LAST_SYNC_DB_TIMESTAMP"; @Autowired private SysShiroService sysShiroService; public OnlineSessionDAO() { super(); } public OnlineSessionDAO(long expireTime) { super(); } /** * 根据会话ID获取会话 * * @param sessionId 会话ID * @return ShiroSession */ @Override protected Session doReadSession(Serializable sessionId) { return sysShiroService.getSession(sessionId); } @Override public void update(Session session) throws UnknownSessionException { super.update(session); } /** * 更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用 */ public void syncToDb(OnlineSession onlineSession) { Date lastSyncTimestamp = (Date) onlineSession.getAttribute(LAST_SYNC_DB_TIMESTAMP); if (lastSyncTimestamp != null) { boolean needSync = true; long deltaTime = onlineSession.getLastAccessTime().getTime() - lastSyncTimestamp.getTime(); if (deltaTime < dbSyncPeriod * 60 * 1000) { // 时间差不足 无需同步 needSync = false; } // isGuest = true 访客 boolean isGuest = onlineSession.getUserId() == null || onlineSession.getUserId() == 0L; // session 数据变更了 同步 if (isGuest == false && onlineSession.isAttributeChanged()) { needSync = true; } if (needSync == false) { return; } } // 更新上次同步数据库时间 onlineSession.setAttribute(LAST_SYNC_DB_TIMESTAMP, onlineSession.getLastAccessTime()); // 更新完后 重置标识 if (onlineSession.isAttributeChanged()) { onlineSession.resetAttributeChanged(); } AsyncManager.me().execute(AsyncFactory.syncSessionToDb(onlineSession)); } /** * 当会话过期/停止(如用户退出时)属性等会调用 */ @Override protected void doDelete(Session session) { OnlineSession onlineSession = (OnlineSession) session; if (null == onlineSession) { return; } onlineSession.setStatus(OnlineStatus.off_line); sysShiroService.deleteSession(onlineSession); } }