issue #69 添加Session的支持

This commit is contained in:
Daniel Qian
2015-01-21 16:01:33 +08:00
parent 7ea6e3ec03
commit 4accbe6ec2
10 changed files with 205 additions and 35 deletions

View File

@@ -39,11 +39,9 @@ public interface InternalSession {
void access();
/**
* Set the <code>isNew</code> flag for this session.
*
* @param isNew The new value for the <code>isNew</code> flag
* End the access.
*/
void setNew(boolean isNew);
void endAccess();
/**
* Set the creation time for this session. This method is called by the

View File

@@ -4,6 +4,7 @@ import me.chanjar.weixin.common.util.res.StringManager;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class SessionImpl implements WxSession, InternalSession {
@@ -90,11 +91,6 @@ public class SessionImpl implements WxSession, InternalSession {
*/
protected volatile boolean isValid = false;
/**
* Flag indicating whether this session is new or not.
*/
protected boolean isNew = false;
/**
* We are currently processing a session expiration, so bypass
* certain IllegalStateException tests. NOTE: This value is not
@@ -123,11 +119,6 @@ public class SessionImpl implements WxSession, InternalSession {
*/
protected volatile long thisAccessedTime = creationTime;
/**
* The last accessed time for this Session.
*/
protected volatile long lastAccessedTime = creationTime;
/**
* The default maximum inactive interval for Sessions created by
* this Manager.
@@ -140,9 +131,15 @@ public class SessionImpl implements WxSession, InternalSession {
*/
protected transient InternalSessionFacade facade = null;
/**
* The access count for this session.
*/
protected transient AtomicInteger accessCount = null;
public SessionImpl(InternalSessionManager manager) {
this.manager = manager;
this.accessCount = new AtomicInteger();
}
@@ -176,7 +173,28 @@ public class SessionImpl implements WxSession, InternalSession {
@Override
public boolean isValid() {
return isValid;
if (!this.isValid) {
return false;
}
if (this.expiring) {
return true;
}
if (accessCount.get() > 0) {
return true;
}
if (maxInactiveInterval > 0) {
long timeNow = System.currentTimeMillis();
int timeIdle;
timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L);
if (timeIdle >= maxInactiveInterval) {
expire();
}
}
return this.isValid;
}
@Override
@@ -215,6 +233,8 @@ public class SessionImpl implements WxSession, InternalSession {
// Mark this session as "being expired"
expiring = true;
accessCount.set(0);
// Remove this session from our manager's active sessions
manager.remove(this, true);
@@ -238,23 +258,23 @@ public class SessionImpl implements WxSession, InternalSession {
public void access() {
this.thisAccessedTime = System.currentTimeMillis();
accessCount.incrementAndGet();
}
@Override
public void setNew(boolean isNew) {
public void endAccess() {
this.isNew = isNew;
this.thisAccessedTime = System.currentTimeMillis();
accessCount.decrementAndGet();
}
@Override
public void setCreationTime(long time) {
this.creationTime = time;
this.lastAccessedTime = time;
this.thisAccessedTime = time;
}

View File

@@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
public class SessionManagerImpl implements WxSessionManager, InternalSessionManager {
@@ -104,6 +105,11 @@ public class SessionManagerImpl implements WxSessionManager, InternalSessionMana
*/
protected int processExpiresFrequency = 6;
/**
* 后台清理线程是否已经开启
*/
private final AtomicBoolean backgroundProcessStarted = new AtomicBoolean(false);
@Override
public void remove(InternalSession session) {
remove(session, false);
@@ -155,7 +161,6 @@ public class SessionManagerImpl implements WxSessionManager, InternalSessionMana
InternalSession session = createEmptySession();
// Initialize the properties of the new session and return it
session.setNew(true);
session.setValid(true);
session.setCreationTime(System.currentTimeMillis());
session.setMaxInactiveInterval(this.maxInactiveInterval);
@@ -191,6 +196,26 @@ public class SessionManagerImpl implements WxSessionManager, InternalSessionMana
@Override
public void add(InternalSession session) {
// 当第一次有session创建的时候开启session清理线程
if (!backgroundProcessStarted.getAndSet(true)) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
// 每秒清理一次
Thread.sleep(1000l);
backgroundProcess();
} catch (InterruptedException e) {
log.error("SessionManagerImpl.backgroundProcess error", e);
}
}
}
});
t.setDaemon(true);
t.start();
}
sessions.put(session.getIdInternal(), session);
int size = getActiveSessions();
if( size > maxActive ) {

View File

@@ -2,9 +2,19 @@ package me.chanjar.weixin.common.session;
public interface WxSessionManager {
/**
* 获取某个sessionId对应的session,如果sessionId没有对应的session则新建一个并返回。
* @param sessionId
* @return
*/
public WxSession getSession(String sessionId);
/**
* 获取某个sessionId对应的session,如果sessionId没有对应的session若create为true则新建一个否则返回null。
* @param sessionId
* @param create
* @return
*/
public WxSession getSession(String sessionId, boolean create);