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对象 ...
随机推荐
- putty 、xshell的使用 和 putty 、xshell、 shell 间免密登陆
相关软件的使用: ######################################################################### 以上是相关软件的使用! 以下是免密 ...
- Wood Chipping Text Animation
Blender Tutorial: Wood Chipping Text Animationhttps://www.youtube.com/watch?v=YFmN7eTNfNw 文字建模 木板建模, ...
- Redis(二)持久化
Redis持久化,分为RDB方式和AOF方式,它们可以单独使用,也可以混用.Redis默认的是使用RDB方式. 一.RDB方式 1.触发快照的方式 RDB方式是在指定时间间隔内某一时间点的数据集快照. ...
- msyql开启慢查询以及分析慢查询
慢查询的用途是用来发现执行时间长的查询语句,以便对这些语句进行优化 [mysqld] #在这里面增加,其它地方无效 #server-id=1 #log-bin=master-bin slow_quer ...
- java.lang.NoClassDefFoundError: org/apache/jute/CsvOutputArchive
1. 问题 看到上面的错误 你怎么想? 包冲突?我这里不是.项目用到了zookeeper,这个类是zookeeper的核心包里的类. 控制台一直打印这个错误 但是项目不影响使用,奇怪! 2. 解决办法 ...
- Big-endian/Little-endian, LSB/MSB
Least significant byte (LSB) Most significant byte (MSB) Big-endian machines store the most-signific ...
- leetcode第一刷_Insert Interval
这道题的难度跟微软的那道面试题相当. 要在集合中插入一段新的集合,相当于求两个集合的并了.对于新增加一段集合的情况,分为以下几种: 1. 增加段跟原来的全然相交,也即他的起点和终点都在被包括在原来的段 ...
- 高维数据的高速近期邻算法FLANN
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jinxueliu31/article/details/37768995 高维数据的高速近期邻算法FL ...
- java中的ArrayList 、List、LinkedList、Collection
原文地址: http://www.cnblogs.com/liqiu/p/3302607.html 一.基础介绍(Set.List.Map) Set(集):集合中的元素不按特定方式排序,并且没有重复对 ...
- 记一次服务器路由跟踪 (2019-01-23 TODO)
记一次服务器路由跟踪 有用户反馈网站 无法访问. 现象如下: ping 没有反馈,确认了可以 ping 通其它的网站. tracert 跟踪到服务器商的内部就没的反应了. 同样一家的服务器商,另外一台 ...