游戏中的各种用户会话必须进行持久化,比如用户会话的创建时间,会话最后更新时间,当前上线时间等,有时候还可能会对该用户进行锁定,这时就有需要再定义禁止上线时间。当然用户的权限也要进行辨别,之前文章说过会有三种可能的用户(游客,平台用户,游戏用户),如何在会话中区分这三种用户的session呢?相关代码如下:
/** 保存于Cookie中的 sessionId 的 key。 */ public static final String COOKIE_KEY = "session_cookie_key"; /** 保存于 Memcached 中的 sessionId 的 key 前缀。 */ public static final String MEMCACHED_KEY_PREFIX = "session_memcached_key__"; /** 游客的 sessionId 的前缀。 */ public static final String GUEST_SESSION_PREFIX = "guest"; /** 平台用户(未进入游戏)的前缀。 */ public static final String PLATFORM_SESSION_PREFIX = "platform"; /** 游戏用户的 sessionId 前缀。 */ public static final String GAMER_SESSION_PREFIX = "gamer"; /** * 检查此会话是否是游戏用户会话。 * * @return 如果是游戏用户会话,则返回 {@code true},否则返回 {@code false}。 */ public boolean isGamerSession() { return StringUtils.split(id, "_").length == 3 && StringUtils.startsWith(id, GAMER_SESSION_PREFIX); } /** * 检查此会话是否是游客会话。 * * @return 如果是游客会话,则返回 {@code true},否则返回 {@code false}。 */ public boolean isGuestSession() { return StringUtils.isEmpty(id) || StringUtils.startsWith(id, GUEST_SESSION_PREFIX); } /** * 检查此会话是否是平台用户会话。 * * @return 如果是平台用户会话,则返回 {@code true},否则返回 {@code false}。 */ public boolean isPlatformSession() { return StringUtils.startsWith(id, PLATFORM_SESSION_PREFIX); }代码中用到了会话id字段,定义如下:
private String id;
/**
* 返回会话Id。
* 会话id表现形式如下:
* <pre>
* 游客会话格式:guest_{random_string} - 保存于Cookie和线程变量。
* 平台用户格式:platform_{accId}_{random_string} - 保存于Cookie和线程变量。
* 游戏用户格式:gamer_{accId}_{areaId} - 保存于Memcached、Cookie和线程变量。
* </pre>
*/
这里只是定义了一个sessionbean,并没有对session进行相关操作,比如取出指定条件对应的session,删除指定条件对应session,销毁session,刷新session等操作,这时需要写一个操作session的类,想到的还是面向接口编程,定义一个接口,里面定义一些相关方法,之后实现此接口使用封装好的cacheutil类来进行对session的具体增删改。实现方式类似于memcache的实现。
在生成sessionid时需要进行sessionid的区分存储,比如上面的guest_{random_string}的类似多种形式,于是就封装了一个方法,代码如下:
/***array[]数组包括sessionid的前缀如guest和一些随机数如上面的random_string,separator表示分隔符如上面的_,startIndex默认为0,endIndex默认为array.length*/public static String join(Object array[], String separator, int startIndex, int endIndex)
{
if(array == null)
return null;
if(separator == null)
separator = "";
int bufSize = endIndex - startIndex;
if(bufSize <= 0)
return "";
bufSize *= (array[startIndex] != null ? array[startIndex].toString().length() : 16) + separator.length();
StringBuilder buf = new StringBuilder(bufSize);
for(int i = startIndex; i < endIndex; i++)
{
if(i > startIndex)
buf.append(separator);
if(array[i] != null)
buf.append(array[i]);
}
return buf.toString();
}
这时要生成sessionid只需要:
public static String generateSessionId(Long id1, Long id2) {
String randomStr = RandomStringUtils.random(8, true, true);//此方法可查看apache common包的相关介绍
String sessionId = null;
if (accId == null) { // 游客
sessionId = StringUtils.join(new Object[] {
SessionBean.GUEST_SESSION_PREFIX, randomStr
}, "_");
} else {
// 平台帐号
if (areaId == null) {
sessionId = StringUtils.join(new Object[] {
SessionBean.PLATFORM_SESSION_PREFIX, id1, randomStr
}, "_");
} else { // 游戏号
sessionId = StringUtils.join(new Object[] {
SessionBean.GAMER_SESSION_PREFIX, id1, id2
}, "_");
}
}
return sessionId;
}这样就可以生成相应的用户sessionid。并在以后对sessionid进行相关处理时就更为简便。