MINA中的reactor

启动时

SocketAcceptor代码
服务启动时将ioHandler和acceptor绑定

        IoHandler ioHandler = new DefaultIoHandler(this);
        try {
    
    
            if (null == bindIP) {
    
    
                acceptor.bind(new InetSocketAddress(port), ioHandler);

bind的主要代码如下

        synchronized (lock) {
    
    
            //启动worker。注意只有一个worker线程
            startupWorker();
    	    //向注册queue中添加
            registerQueue.add(request);
            //让所有阻塞在selector上的请求立即返回
            selector.wakeup();
        }

        try {
    
    
            //一个countdownLatch 在worker中处理后会进行countdown
            request.done.await();
        } catch (InterruptedException e) {
    
    
            ExceptionMonitor.getInstance().exceptionCaught(e);
        }

worker执行的代码如下

                    int nKeys = selector.select();
                    //从registerQueue中获取SocketChannel并将其注册到selector上
                    registerNew();

                    if (nKeys > 0) {
    
    
                        //下一节的内容
                        processSessions(selector.selectedKeys());
                    }

                    cancelKeys();

                    if (selector.keys().isEmpty()) {
    
    
                        synchronized (lock) {
    
    
                            if (selector.keys().isEmpty()
                                    && registerQueue.isEmpty()
                                    && cancelQueue.isEmpty()) {
    
    
                                worker = null;
                                try {
    
    
                                    selector.close();
                                } catch (IOException e) {
    
    
                                    ExceptionMonitor.getInstance()
                                            .exceptionCaught(e);
                                } finally {
    
    
                                    SocketAcceptor.this.selector = null;
                                }
                                break;
                            }
                        }
                    }

接受新连接时

每一个SocketAcceptor都持有一群SocketIoProcessor作为打工的小弟。

    private final SocketIoProcessor[] ioProcessors;


    private SocketIoProcessor nextProcessor() {
    
    
        if (this.processorDistributor == Integer.MAX_VALUE) {
    
    
            this.processorDistributor = Integer.MAX_VALUE % this.processorCount;
        }

        return ioProcessors[processorDistributor++ % processorCount];
    }

在上面的processSessions会调用新其的org.apache.mina.transport.socket.nio.SocketIoProcessor#addNew来交给小弟这个连接。

    void addNew(SocketSessionImpl session) throws IOException {
    
    
        newSessions.add(session);
        startupWorker();
    }

每个小弟会为每一个session启动一个worker线程
worker的核心代码如下

                    int nKeys = selector.select(1000);
                    //从newSessions队列中拿到channel并注册到selector上
                    doAddNew();
                    doUpdateTrafficMask();

                    if (nKeys > 0) {
    
    
                        //处理数据接受事件
                        process(selector.selectedKeys());
                    }

                    doFlush();
                    doRemove();
                    notifyIdleness();

接受数据时

                session.getFilterChain().fireMessageReceived(session, buf);

沿着AbstractIoFilterChain,一直调用到TailFilter,这时调用用户的DefaultIoHandler。

        public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
    
    
            try {
    
    
                session.getHandler().messageReceived(session, message);
            } finally {
    
    
                ByteBufferUtil.releaseIfPossible(message);
            }

        }

猜你喜欢

转载自blog.csdn.net/define_us/article/details/111499922