MINA学习笔记四——第三章Session
第四章 会话
会话是MINA的核心:每次一个客户端连接到服务器,一个新的会话将被创建,而且该会话在客户端连接关闭前将一直驻留在内存中。
在一个会话的整个生命周期中,它被用于存储连接的持久化信息,以及服务器在处理请求过程中所需要的其他附加信息。
4.1 会话状态
每个会话都有一个状态,而且这个状态在随着时间不断变化:
(1)已连接:会话已经被创建并且是可用的
(2)空闲:会话至少已经有一个时间周期没有处理过请求了(这个周期的时间是可配置的)。
a)读空闲:一个周期内没有实际的读操作
b)写空闲:一个周期内没有实际的写操作
c)双空闲:一个周期内没有读、写操作
(3)正在关闭:会话正在关闭(剩余的消息正在刷新,清理工作还未结束)
(4)已关闭:会话已关闭。无法再次**它。
下图是会话所有可能的状态转换:
<!--[endif]-->
4.2配置
可以通过设置不同的参数来获取一个定制的会话:
(1)接收缓冲区大小
(3)空闲时间
(4)写超时时间
还有另外一些配置是依赖于所使用的传输协议的(具体参考第六章)。
4.3管理用户定义的属性
为了存储一些以后会用到的数据,自定义一些属性是必须的。可以通过为每个会话所关联专用的数据结构来实现的。这是一个key-value的键值对,可以存储开发者可能想保存的任何数据类型。
举例来说,如果你想追踪在会话建立以后一个用户发送的请求总数,可以简单地通过创建一个key来关联请求总数并将其保存到这个map即可。代码如下:
int counterValue = session.getAttribute("counter");
session.setAttribute("counter", counterValue +1);
我们有一个方案来处理存储在会话中的属性:每个属性是一个键值对的一个组成部分,可以在会话的容器中添加、删除和读取。
这个容器在会话被创建时自动创建,在会话终止时销毁。
4.4自定义容器
就像我们说的,这个容器是一个键值对,缺省的实现是一个Map。但有些时候,我们可能需要定义其他的数据结构来存储需要长期存活的数据或者是避免在内存中存储超大数据,可以通过实现一个接口和一个用于在会话创建时创建容器的工厂。
一些代码片段展示了如何在会话初始化时创建容器:
protectedfinalvoidinitSession(IoSession session,
IoFuture future, IoSessionInitializer sessionInitializer){
...
try{
((AbstractIoSession) session).setAttributeMap(session.getService()
.getSessionDataStructureFactory().getAttributeMap(session));
}catch(IoSessionInitializationException e){
throw e;
}catch(Exception e){
thrownewIoSessionInitializationException(
"Failed to initialize an attributeMap.", e);
}
接下来的代码展示了如果我们想要定义一个其他类型容器所需要实现的接口。
public interface IoSessionDataStructureFactory {
/**
* Returns an {@link IoSessionAttributeMap} which is going to be associated
* with the specified <tt>session</tt>. Please note that the returned
* implementation must be thread-safe.
*/
IoSessionAttributeMap getAttributeMap(IoSession session) throws Exception;
}
4.5过滤器链
每个会话都关联一个过滤器链,用于处理接收到的请求或发出的信息。这些过滤器是可以独立于每一个会话的,但大多数情况请,我们对所有现存的会话使用非常相似的过滤器。
当然,我们也可能为了一个会话而动态修改过滤器,例如为一个特别的会话添加一个日志过滤器。
4.6 统计
每一个会话都保留着一份记录,记录这个会话干了些啥:
(1)发送和接收的字节总数
(2)发送和接收的消息总数
(3)空闲状态
(4)吞吐量
和许多其他有用的信息。
4.7 处理器
最后,很重要的一点,一个会话通过其关联的处理器来调度你应用中的消息。这个处理器也通过简单地调用会话的write()方法来来发送回复。
...
session.write(<your message>);
...