mina2中的session
简介
session类图
// 创建服务器监听
IoAcceptor acceptor = new NioSocketAcceptor();
// 设置buffer的长度
acceptor.getSessionConfig().setReadBufferSize(2048);
// 设置连接超时时间
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
session做为一个连接的具体对象,缓存当前连接用户的一些信息。
WriteFuture write(Object message);
WriteFuture write(Object message, SocketAddress destination);
下面着重分析创建过程以及session的状态
创建与初始化
protected NioSession accept(IoProcessor<NioSession> processor, ServerSocketChannel handle) throws Exception { SelectionKey key = handle.keyFor(selector); if ((key == null) || (!key.isValid()) || (!key.isAcceptable())) {
return null;
} // accept the connection from the client
SocketChannel ch = handle.accept(); if (ch == null) {
return null;
} return new NioSocketSession(this, processor, ch);
}
protected final void initSession(IoSession session, IoFuture future, IoSessionInitializer sessionInitializer) {
// Update lastIoTime if needed.
if (stats.getLastReadTime() == 0) {
stats.setLastReadTime(getActivationTime());
} if (stats.getLastWriteTime() == 0) {
stats.setLastWriteTime(getActivationTime());
} // Every property but attributeMap should be set now.
// Now initialize the attributeMap. The reason why we initialize
// the attributeMap at last is to make sure all session properties
// such as remoteAddress are provided to IoSessionDataStructureFactory.
try {
((AbstractIoSession) session).setAttributeMap(session.getService().getSessionDataStructureFactory()
.getAttributeMap(session));
} catch (IoSessionInitializationException e) {
throw e;
} catch (Exception e) {
throw new IoSessionInitializationException("Failed to initialize an attributeMap.", e);
} try {
((AbstractIoSession) session).setWriteRequestQueue(session.getService().getSessionDataStructureFactory()
.getWriteRequestQueue(session));
} catch (IoSessionInitializationException e) {
throw e;
} catch (Exception e) {
throw new IoSessionInitializationException("Failed to initialize a writeRequestQueue.", e);
} if ((future != null) && (future instanceof ConnectFuture)) {
// DefaultIoFilterChain will notify the future. (We support ConnectFuture only for now).
session.setAttribute(DefaultIoFilterChain.SESSION_CREATED_FUTURE, future);
} if (sessionInitializer != null) {
sessionInitializer.initializeSession(session, future);
} finishSessionInitialization0(session, future);
}
private final Queue<S> newSessions = new ConcurrentLinkedQueue<S>(); /** A queue used to store the sessions to be removed */
private final Queue<S> removingSessions = new ConcurrentLinkedQueue<S>(); /** A queue used to store the sessions to be flushed */
private final Queue<S> flushingSessions = new ConcurrentLinkedQueue<S>(); /**
* A queue used to store the sessions which have a trafficControl to be
* updated
*/
private final Queue<S> trafficControllingSessions = new ConcurrentLinkedQueue<S>(); /** The processor thread : it handles the incoming messages */
private final AtomicReference<Processor> processorRef = new AtomicReference<Processor>();
private class Processor implements Runnable {
public void run() {
for (;;) {
long t0 = System.currentTimeMillis();
int selected = select(SELECT_TIMEOUT);
long t1 = System.currentTimeMillis();
long delta = (t1 - t0); if ((selected == 0) && !wakeupCalled.get() && (delta < 100)) {
if (isBrokenConnection()) {
wakeupCalled.getAndSet(false);
continue;
} else {
registerNewSelector();
}
wakeupCalled.getAndSet(false);
continue;
} nSessions += handleNewSessions(); updateTrafficMask(); if (selected > 0) {
process();
} nSessions -= removeSessions(); }
}
}
1、不断地调用select方法来检查是否有session准备就绪,如果没有或者间隔时间小于100ms则检查selector是否可用,如果不可用重新建一个selector(这里linux下的epoll的问题可能导致selector不可用。)
private void process(S session) {
// Process Reads
if (isReadable(session) && !session.isReadSuspended()) {
read(session);
} // Process writes
if (isWritable(session) && !session.isWriteSuspended()) {
// add the session to the queue, if it's not already there
if (session.setScheduledForFlush(true)) {
flushingSessions.add(session);
}
}
}
状态
IoFilter与IoHandler就是在这些状态上面加以干预,下面重点看一下IDLE状态,它分三种:
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
每隔一秒一检查是否到达了设置的空闲时间
private static void notifyIdleSession0(IoSession session, long currentTime, long idleTime, IdleStatus status,
long lastIoTime) {
if ((idleTime > 0) && (lastIoTime != 0) && (currentTime - lastIoTime >= idleTime)) {
session.getFilterChain().fireSessionIdle(status);
}
}
如果当前时间减去上一次IDLE事件触发的时间大于用户设置的idleTime,则触发一次sessionIdle事件。
public void fireSessionIdle(IdleStatus status) {
session.increaseIdleCount(status, System.currentTimeMillis());
Entry head = this.head;
callNextSessionIdle(head, session, status);
}
increaseIdleCount这个方法会更新lastToTime的值为当前时间,紧接着穿透过滤器链(当然在过滤器的sessionIdle中可能会做一些操作)到达IoHandler的sessionIdle方法,如果需要在session空闲的时候做一些操作,就可以在这个方法里面做。
mina2中的session的更多相关文章
- 在 ASP.NET CORE 中使用 SESSION
Session 是保存用户和 Web 应用的会话状态的一种方法,ASP.NET Core 提供了一个用于管理会话状态的中间件.在本文中我将会简单介绍一下 ASP.NET Core 中的 Session ...
- Tomcat中的Session小结
什么是Session 对Tomcat而言,Session是一块在服务器开辟的内存空间,其存储结构为ConcurrentHashMap: Session的目的 Http协议是一种无状态协议,即每次服务端 ...
- .ashx中使用Session
在一般处理程序中给session赋值是报错:未将对象引用设置到对象的实例.
- strust2中使用session
在Struts2里,如果需要在Action中使用session,可以通过下面两种方式得到1.通过ActionContext class中的方法getSession得到2.Action实现org.apa ...
- 在IHttpHandler中获取session
因为业务要异步通过IHttpHandler获得数据,但还要根据当前登录人员的session过滤,因此要在在IHttpHandler中获取session 方法是HttpHandler容器中如果需要访问S ...
- Java中对session的简单操作
1.jsp中操作session <% String name=(String)request.getSession().getAttribute("username"); / ...
- ASP.NET中的Session怎么正确使用
Session对象用于存储从一个用户开始访问某个特定的aspx的页面起,到用户离开为止,特定的用户会话所需要的信息.用户在应用程序的页面切换时,Session对象的变量不会被清除. 对于一个Web应用 ...
- 如何在报表权限中使用session
1. 问题描述 权限中使用session,一般是用来存放用户名和密码,下面以报表开发工具FineReport为例,分两种情况介绍用户名和密码的保存: 2. 同一应用下session 由于session ...
- [转]tomcat中的session管理
转载地址:http://blog.csdn.net/iloveqing/article/details/1544958 当一个sesson开始时,Servlet容器会创建一个HttpSession对象 ...
随机推荐
- 1001.A+B Format (20)题目解答
前言 最开始看到这个题目,我的第一个想法是有没有那种输出格式可以直接拿来用的,然后我百度了一下,想偷懒,然而并没有这种东西.只好动动自己的脑子了. 关于GitHub 这个问题,当初我弄了五天才建立好联 ...
- this语句的用法第一、二点
1.this是js的一个关键字,指定一个对象然后去代替他. 函数内的this和函数外的this,函数内的this指向行为发生的主体.函数外的this都指向window没有意思. 例题: functio ...
- SQL经常使用的一些词
sp_helptext: 例:exec sp_helptext proc_name(查看存储过程的定义) sp_rename: 例:exec sp_rename 'proc_name1','proc_ ...
- php基础-3
php的数据类型 字符串 字符串的声明:$str = "aaa"; 字符串的方法 strpos(str, find_str):该方法在一个字符串中查找需要查找的字符串,并回来该字符 ...
- JAVA的初始化顺序:
JAVA的初始化顺序: 父类的静态成员初始化>父类的静态代码块>子类的静态成员初始化>子类的静态代码块>父类的代码块>父类的构造方法>子类的代码块>子类的构造 ...
- Go Example--值运算
package main import "fmt" //通过import导入fmt标准包 func main() { //+号可以用做连接字符串 fmt.Println(" ...
- LeetCode – Most Common Word
Given a paragraph and a list of banned words, return the most frequent word that is not in the list ...
- 取消svn关联文件夹
svn没有自带取消svn关联功能,所以我们需要以下脚本 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classe ...
- Gravitee.io api gateway 试用
以前写过几篇关于整体介绍的以及 使用docker 运行的简单说明,有了docker-compose 环境我们可以 方便的进行测试使用了. 环境准备 docker-compose 文件 versio ...
- memsql kafka集成
memsql 可以加载s3,文件系统,kafka.hdfs 系统的数据,测试使用kafka 环境使用 docker-compose 运行,新版本的需要申请license,参考链接: https://w ...