mina源码分析---3

原创 2015年11月18日 22:22:42

process源码分析

上一章分析了processHandles函数,本章开始将要分析processHandles中的process函数,该函数是处理客户端请求的核心函数。process定义在AbstractPollingIoProcessor中,

    private void process() throws Exception {
        for (Iterator<S> i = selectedSessions(); i.hasNext();) {
            S session = i.next();
            process(session);
            i.remove();
        }
    }

这里就是依次取出Nio中发生相应时间的NioSocketSession,并进一步执行process函数,

    private void process(S session) {

        if (isReadable(session) && !session.isReadSuspended()) {
            read(session);
        }

        if (isWritable(session) && !session.isWriteSuspended()) {
            if (session.setScheduledForFlush(true)) {
                flushingSessions.add(session);
            }
        }
    }

isReadable和isWritable用于判断Nio中产生的key是哪种时间,isReadSuspended和isWriteSuspended则就是两个bool变量,用于控制读写。下面假设判定通过,如果是写事件,则很简单,将该Session添加进flushingSessions后,后续便能写入写缓存中(查看上一章的flush函数)。这里主要分析读事件,

read

    private void read(S session) {
        IoSessionConfig config = session.getConfig();
        int bufferSize = config.getReadBufferSize();
        IoBuffer buf = IoBuffer.allocate(bufferSize);

        final boolean hasFragmentation = session.getTransportMetadata().hasFragmentation();

        try {
            int readBytes = 0;
            int ret;

            try {
                if (hasFragmentation) {

                    while ((ret = read(session, buf)) > 0) {
                        readBytes += ret;

                        if (!buf.hasRemaining()) {
                            break;
                        }
                    }
                } else {
                    ret = read(session, buf);

                    if (ret > 0) {
                        readBytes = ret;
                    }
                }
            } finally {
                buf.flip();
            }

            if (readBytes > 0) {
                IoFilterChain filterChain = session.getFilterChain();
                filterChain.fireMessageReceived(buf);
                buf = null;

                if (hasFragmentation) {
                    if (readBytes << 1 < config.getReadBufferSize()) {
                        session.decreaseReadBufferSize();
                    } else if (readBytes == config.getReadBufferSize()) {
                        session.increaseReadBufferSize();
                    }
                }
            }
        } catch (Exception e) {

        }
    }

该函数主要做了两件事情,一是调用read通过Nio的Channel将数据读进缓存中,二是调用IoFilterChain的fireMessageReceived函数。先看read函数,具体的读函数read定义在NioProcessor中,

    protected int read(NioSession session, IoBuffer buf) throws Exception {
        ByteChannel channel = session.getChannel();

        return channel.read(buf.buf());
    }

这里就是简单的调用Nio的Channel将数据读入缓存,具体的过程可以参考Nio的源码。
回到前面的read函数中,如果读入数据成功,就从NioSocketSession中获取IoFilterChain并调用其fireMessageReceived函数,getFilterChain返回的IoFilterChain是DefaultIoFilterChain。
在使用mina框架时,开发者可以定义自己的过滤器添加进mina中,mina默认实现了两个过滤器,看DefaultIoFilterChain的构造函数,

    public DefaultIoFilterChain(AbstractIoSession session) {
        if (session == null) {
            throw new IllegalArgumentException("session");
        }

        this.session = session;
        head = new EntryImpl(null, null, "head", new HeadFilter());
        tail = new EntryImpl(head, null, "tail", new TailFilter());
        head.nextEntry = tail;
    }

因此,mina框架默认实现了HeadFilter和TailFilter。

fireMessageReceived

fireMessageReceived定义在DefaultIoFilterChain中,

    public void fireMessageReceived(Object message) {
        if (message instanceof IoBuffer) {
            session.increaseReadBytes(((IoBuffer) message).remaining(), System.currentTimeMillis());
        }

        callNextMessageReceived(head, session, message);
    }

这里就是简单调用callNextMessageReceived进行进一步的处理,传入的参数head是过滤器链表的指针头,session是NioSocketSession,message就是读入的数据。

    private void callNextMessageReceived(Entry entry, IoSession session, Object message) {
        try {
            IoFilter filter = entry.getFilter();
            NextFilter nextFilter = entry.getNextFilter();
            filter.messageReceived(nextFilter, session, message);
        } catch (Exception e) {

        } 
    }

这里就是从entry中取出过滤器filter,调用其messageReceived函数。默认必然会取出2个filter,一个是HeadFilter,另一个是TailFilter。其中,HeadFilter在处理消息时什么都不会做,TailFilter的messageReceived如下

        public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
            AbstractIoSession s = (AbstractIoSession) session;

            try {
                session.getHandler().messageReceived(s, message);
            } finally {
                if (s.getConfig().isUseReadOperation()) {
                    s.offerReadFuture(message);
                }
            }
        }

因此,TailFilter会调用其中的注册的handler对消息进行处理,getHandler返回的是一个IoHandler。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

mina3源码分析,启动过程分析(一)

上图为服务端TCPServer类的继承关系,主要实现了IoServer和IoService两个接口,IoServer定义了bind、unbind等绑定地址的操作,IoService主要定义了Filte...

Mina-2.0.7源码学习 (3) ------ IoBuffer

Mina中的 IoBuffer 主要是对 Java NIO 中 ByteBuffer 的封装,

MINA源码分析2-I/O操作

分析I/O操作首先我们从NioSocketAcceptor

Mina2源码分析

  • 2013-05-17 10:23
  • 558KB
  • 下载

MINA源码分析---对客户端设置连接间隔时间的过滤器

如果这个IP此次发起连接距离上次发起连接的时间少于规定的时间,则关闭会话,否则建立会话,可以避免同一个远程主机在短时间内发起多个连接 下面是源代码,比较简单明了,不作解释了 厅 /* * Li...

MINA框架源码分析(二)

上一篇我们通过实例学习了MINA框架的用法,发现用起来还是挺方便的,就那么几步就可以了,本着学东西必知其原理的观念,决定看看MINA的源码实现,好了,我们开始吧!         MINA源码对于客户...

关于MINA服务端源码分析

1:NioSocketAcceptor.java 他是继承了AbstractPollingIoAcceptor.java 和 AbstractIoAcceptor.java

MINA源码分析1-服务端启动和客户端调用

最近由于需要使用MINA框架进行项目开发,所以研究了

MINA源码分析1:服务器端的启动过程

一、预备: 这篇文章假设你了解java nio 有关Java NIO的资料: 1. http://tutorials.jenkov.com/java-nio/index.html英文的,国内有很多博客...

Mina源码分析——IoService

这两天看了下Mina和Netty的源码,想比较来说Mina的结构简洁易懂。Mina和Netty出自同一人,而Netty是作者对Mina的重构版,改进了很多。如果学习网络编程的话,个人建议从Mina开始...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)