Mina源码总结(二)

一、Client

1、IoConnector:Client端的最底层接口。主要有3个方法:超时时间(ConnectTimeoutMillis),目标地址(RemoteAddress),创建连接(connect).

2、abstractIoConnector:实现了IoConnector,继承了AbstractIoService。继承了AbstractIoService同Server端一样,不再赘述。

3、abstractPollingIoConnector:

protected final ConnectFuture connect0(SocketAddress remoteAddress, SocketAddress localAddress,
            IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
        H handle = null;
        boolean success = false;
        try {
            //SocketChannel sc = SocketChannel.open();
            handle = newHandle(localAddress);
            //返回true的条件是,对该地址进行的connect可以立即建立
            if (connect(handle, remoteAddress)) {
                ConnectFuture future = new DefaultConnectFuture();
                //new NioSocketSession
                T session = newSession(processor, handle);
                initSession(session, future, sessionInitializer);
                //通过IoProcessor注册和处理READ和WRITE事件,同Server端。
                session.getProcessor().add(session);
                success = true;
                return future;
            }

            success = true;
        } catch (Exception e) {
            return DefaultConnectFuture.newFailedFuture(e);
        } finally {
            if (!success && handle != null) {
                try {
                    close(handle);
                } catch (Exception e) {
                    ExceptionMonitor.getInstance().exceptionCaught(e);
                }
            }
        }
        //创建请求,放到队列中
        ConnectionRequest request = new ConnectionRequest(handle, sessionInitializer);
        connectQueue.add(request);
        //执行Connector内部类
        startupWorker();
        wakeup();

        return request;
    }
private class Connector implements Runnable {

        public void run() {
            assert (connectorRef.get() == this);

            int nHandles = 0;

            while (selectable) {
                try {
                    //获取超时时间
                    int timeout = (int) Math.min(getConnectTimeoutMillis(), 1000L);
                    //selector.selector();
                    int selected = select(timeout);
                    //注册CONNECTOR事件,从队列中获取request,附着在通道上
                    //handle.register(selector, SelectionKey.OP_CONNECT, request);
                    nHandles += registerNew();

                    // get a chance to get out of the connector loop, if we don't have any more handles
                    if (nHandles == 0) {
                        connectorRef.set(null);

                        if (connectQueue.isEmpty()) {
                            assert (connectorRef.get() != this);
                            break;
                        }

                        if (!connectorRef.compareAndSet(null, this)) {
                            assert (connectorRef.get() != this);
                            break;
                        }

                        assert (connectorRef.get() == this);
                    }

                    if (selected > 0) {
                        //处理CONNECTOR事件,新建Session,通过IoProcessor注册和处理READ和WRITE事件,同Server端。
                        nHandles -= processConnections(selectedHandles());
                    }

                    processTimedOutSessions(allHandles());

                    nHandles -= cancelKeys();
                } catch (ClosedSelectorException cse) {
                    // If the selector has been closed, we can exit the loop
                    ExceptionMonitor.getInstance().exceptionCaught(cse);
                    break;
                } catch (Exception e) {
                    ExceptionMonitor.getInstance().exceptionCaught(e);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e1) {
                        ExceptionMonitor.getInstance().exceptionCaught(e1);
                    }
                }
            }

            if (selectable && isDisposing()) {
                selectable = false;
                try {
                    if (createdProcessor) {
                        processor.dispose();
                    }
                } finally {
                    try {
                        synchronized (disposalLock) {
                            if (isDisposing()) {
                                destroy();
                            }
                        }
                    } catch (Exception e) {
                        ExceptionMonitor.getInstance().exceptionCaught(e);
                    } finally {
                        disposalFuture.setDone();
                    }
                }
            }
        }
    }
总结: Client端和Server端的代码结构十分类似,除了客户端对NIO的初始化不一样,建立Session以及之后对READ和WRITE事件的注册和处理都是和Server端用的相通的类核方法。二、责任链IoFilterChain1、IoFilterChain:内部类Entry是双向链表,是实现此责任链模式的基本数据结构。2、DefaultIoFilterChain

    private class EntryImpl implements Entry {
        //双向链表
        private EntryImpl prevEntry;

        private EntryImpl nextEntry;

        private final String name;
        //当前节点的filter
        private IoFilter filter;

        private final NextFilter nextFilter;
        //构造方法,设置前后节点,当前节点名称,filter
        private EntryImpl(EntryImpl prevEntry, EntryImpl nextEntry, String name, IoFilter filter) {
            if (filter == null) {
                throw new IllegalArgumentException("filter");
            }

            if (name == null) {
                throw new IllegalArgumentException("name");
            }

            this.prevEntry = prevEntry;
            this.nextEntry = nextEntry;
            this.name = name;
            this.filter = filter;
            //匿名内部类创建NextFilter的实例,获取下一个Entry,调用下一个Entry的Filter,递归调用。
            this.nextFilter = new NextFilter() {
                public void sessionCreated(IoSession session) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextSessionCreated(nextEntry, session);
                }

                public void sessionOpened(IoSession session) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextSessionOpened(nextEntry, session);
                }

                public void sessionClosed(IoSession session) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextSessionClosed(nextEntry, session);
                }

                public void sessionIdle(IoSession session, IdleStatus status) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextSessionIdle(nextEntry, session, status);
                }

                public void exceptionCaught(IoSession session, Throwable cause) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextExceptionCaught(nextEntry, session, cause);
                }

                public void inputClosed(IoSession session) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextInputClosed(nextEntry, session);
                }

                public void messageReceived(IoSession session, Object message) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextMessageReceived(nextEntry, session, message);
                }

                public void messageSent(IoSession session, WriteRequest writeRequest) {
                    Entry nextEntry = EntryImpl.this.nextEntry;
                    callNextMessageSent(nextEntry, session, writeRequest);
                }

                public void filterWrite(IoSession session, WriteRequest writeRequest) {
                    Entry nextEntry = EntryImpl.this.prevEntry;
                    callPreviousFilterWrite(nextEntry, session, writeRequest);
                }

                public void filterClose(IoSession session) {
                    Entry nextEntry = EntryImpl.this.prevEntry;
                    callPreviousFilterClose(nextEntry, session);
                }

                public String toString() {
                    return EntryImpl.this.nextEntry.name;
                }
            };
        }

      


    }

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

        this.session = session;
        //会生成头和尾2个节点,这2个节点的Filter不一样,尾节点指向头节点,非循环。
        //尾节点的主要作用的,当责任链到尾部的时候,调用到自己实现的handler,从而可以获取自己需要的事件。
        head = new EntryImpl(null, null, "head", new HeadFilter());
        tail = new EntryImpl(head, null, "tail", new TailFilter());
        //头节点指向尾节点
        head.nextEntry = tail;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值