MINA连接
来源:互联网 发布:java public修饰类 编辑:程序博客网 时间:2024/05/16 04:39
简介
Mina每建立一个连接同时会创建一个session对象,用于保存这次读写需要用到的所有信息。从抽象类AbstractIoSession中可以看出session具有如下功能:
1、从attributes成员可以看出session可以存放用户关心的键值对
2、注意到WriteRequestQueue,这是一个写请求队列,processor中调用flush或者flushNow方法时会将用户写入的数据包装成一个writeRequest对象,并加入这个队列中。
3、提供了大量的统计功能,比如接收到了多少消息、最后读取时间等
在代码中一般是这样使用session的
- // 创建服务器监听
- IoAcceptor acceptor = new NioSocketAcceptor();
- // 设置buffer的长度
- acceptor.getSessionConfig().setReadBufferSize(2048);
- // 设置连接超时时间
- acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
用得最多的是通过session写入数据,这是调用了IoSession的write方法
- WriteFuture write(Object message);
- WriteFuture write(Object message, SocketAddress destination);
创建与初始化
每建立一个连接,就会创建一个session,IoAcceptor的accept方法的返回值正是一个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);
- }
session在创建好后,紧接着就会对其进行初始化。
- protected final void initSession(IoSession session, IoFuture future, IoSessionInitializer sessionInitializer) {
- if (stats.getLastReadTime() == 0) {
- stats.setLastReadTime(getActivationTime());
- }
- if (stats.getLastWriteTime() == 0) {
- stats.setLastWriteTime(getActivationTime());
- }
- 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);
- }
session被初始化好之后会加入到processor中,processor中有一个队列专门存放session:
- private final Queue<S> newSessions = new ConcurrentLinkedQueue<S>();
- 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();
- }
- }
- }
2、从newSessions队列中取出这些session,并将其负责的通道注册到selector上
3、处理准备就绪的session
- 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);
- }
- }
- }
状态
Mina中的session具有状态,且状态之间是可以相互转化的
Connected:session被创建时处于这种状态
Idle:没有请求可以处理(可配置)
Closing:正处于关闭状态(可能正在做一些清理工作)
Closed:关闭状态
下图是这几种状态之间的转化图:
Idle for read:在规定时间内没有数据可读
Idle for write:在规定时间内没有数据可写
Idle for both:在规定时间内没有数据可读和可写
这三种状态分别对应IdleStatus类的三个常量:READER_IDLE、WRITER_IDLE、BOTH_IDLE
前面session的用法中有如下设置:
- acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
- private void notifyIdleSessions( long currentTime )
- {
- // process idle sessions
- if ( currentTime - lastIdleCheckTime >= 1000 )
- {
- lastIdleCheckTime = currentTime;
- AbstractIoSession.notifyIdleness( getListeners().getManagedSessions().values().iterator(), currentTime );
- }
- }
- 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);
- }
- }
- public void fireSessionIdle(IdleStatus status) {
- session.increaseIdleCount(status, System.currentTimeMillis());
- Entry head = this.head;
- callNextSessionIdle(head, session, status);
- }
转自:http://blog.csdn.net/aesop_wubo/article/details/9385551
0 0
- MINA连接
- apache mina 长连接
- MINA连接方式
- Mina 长连接实践
- MINA异步连接框架介绍
- mina长连接ConnectGameServer 类
- Mina的大量连接问题
- Mina长连接Android使用
- Android长连接之mina
- mina实现长连接 推送
- Mina源码阅读笔记(三)-Mina的连接IoAccpetor
- Mina源码阅读笔记(三)-Mina的连接IoAccpetor
- Mina源码阅读笔记(三)-Mina的连接IoAccpetor
- Mina源码阅读笔记(三)-Mina的连接IoAccpetor
- APACHE MINA (异步连接框架)介绍
- apache mina (异步连接框架)介绍
- Mina 解决请求后直接关闭连接
- apache mina (异步连接框架)介绍
- maven打包
- 模仿门口passport访问cookies的方法
- 如何优化JavaScript脚本的性能
- RTLabel的常用标签
- Linux下JVM中可生成的最大Thread数量
- MINA连接
- Jquery省市区/县三级联动代码,以及引用area.js插件
- IOS常用正则表达式
- MySQL备份
- eclipse弹出workspace选择框
- sql优化注意方法
- Redis数据备份与恢复
- CSS---各种分割线
- Android 支付宝 sdk 开发