netty源码分析 之二 transport(bootstrap)

来源:互联网 发布:淘宝钥匙扣定制 编辑:程序博客网 时间:2024/05/07 14:04

transport 分为两部分  bootstrap channel 

由于channel东西比较多,所以分开两篇来写

AbstractBootstrap

顾名思义,引导累   抽象父类, 定义模板方法

成员变量


private volatile EventLoopGroup group;    @SuppressWarnings("deprecation")    private volatile ChannelFactory<? extends C> channelFactory;    private volatile SocketAddress localAddress;    private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();    private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();    private volatile ChannelHandler handler;

核心方法

bind绑定方法  主要为server端提供的。

initAndRegister    最核心的



ServerBootstrap

多了child设置,主线程处理连接,child处理read到的消息

    private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();    private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();    private volatile EventLoopGroup childGroup;    private volatile ChannelHandler childHandler;


看其init方法



ServerBootstrapAcceptor


继承了ChannelHandlerAdapter   主要实现了channelRead  和exceptionCaught  方法, 其主要作用是子线程来处理消息


public void channelRead(ChannelHandlerContext ctx, Object msg) {            final Channel child = (Channel) msg;            child.pipeline().addLast(childHandler);            for (Entry<ChannelOption<?>, Object> e: childOptions) {                try {                    if (!child.config().setOption((ChannelOption<Object>) e.getKey(), e.getValue())) {                        logger.warn("Unknown channel option: " + e);                    }                } catch (Throwable t) {                    logger.warn("Failed to set a channel option: " + child, t);                }            }            for (Entry<AttributeKey<?>, Object> e: childAttrs) {                child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());            }            try {                childGroup.register(child).addListener(new ChannelFutureListener() {                    @Override                    public void operationComplete(ChannelFuture future) throws Exception {                        if (!future.isSuccess()) {                            forceClose(child, future.cause());                        }                    }                });            } catch (Throwable t) {                forceClose(child, t);            }        }


Bootstrap

看完serverBootstap之后,这个类就比较简单了。。 再看下connect方法


同样init方法

void init(Channel channel) throws Exception {        ChannelPipeline p = channel.pipeline();        p.addLast(handler());        final Map<ChannelOption<?>, Object> options = options();        synchronized (options) {            for (Entry<ChannelOption<?>, Object> e: options.entrySet()) {                try {                    if (!channel.config().setOption((ChannelOption<Object>) e.getKey(), e.getValue())) {                        logger.warn("Unknown channel option: " + e);                    }                } catch (Throwable t) {                    logger.warn("Failed to set a channel option: " + channel, t);                }            }        }        final Map<AttributeKey<?>, Object> attrs = attrs();        synchronized (attrs) {            for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {                channel.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());            }        }    }


connect方法也就是

private static void doConnect0(            final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelFuture regFuture,            final ChannelPromise connectPromise) {        // This method is invoked before channelRegistered() is triggered.  Give user handlers a chance to set up        // the pipeline in its channelRegistered() implementation.        final Channel channel = connectPromise.channel();        channel.eventLoop().execute(new Runnable() {            @Override            public void run() {                if (regFuture.isSuccess()) {                    if (localAddress == null) {                        channel.connect(remoteAddress, connectPromise);                    } else {                        channel.connect(remoteAddress, localAddress, connectPromise);                    }                    connectPromise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);                } else {                    connectPromise.setFailure(regFuture.cause());                }            }        });    }




0 0
原创粉丝点击