Netty:options和configs

在使用Netty时,初始化服务端或客户端时,我们经常会看到如下代码

Bootstrap b = new Bootstrap();
......
b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);

通过option方法设置一些选项(参数),它其实是一个Map,维护这键值对,option方法在AbstractBootstrap类中

private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();

@SuppressWarnings("unchecked")
public <T> B option(ChannelOption<T> option, T value) {
	if (option == null) {
		throw new NullPointerException("option");
	}
	if (value == null) {
		synchronized (options) {
			options.remove(option);
		}
	} else {
		synchronized (options) {
			options.put(option, value);
		}
	}
	return (B) this;
}

如果value是null,就会从options中删除这个对象,我们之前传入的ChannelOption.TCP_NODELAY,作为key值,true 作为value值。

ChannelOption有很多选项可以设置,具体可以参见Netty文档http://netty.io/4.1/api/io/netty/channel/ChannelOption.html

当我们要使用设置好的option时,其实是通过Channel的Config去访问的,那我们设置的option是怎样写入Config的呢?以NioSocketChannel为例,初始化时

public NioSocketChannel(Channel parent, SocketChannel socket) {
	super(parent, socket);
	config = new NioSocketChannelConfig(this, socket.socket());
}

这里会创建一个NioSocketChannelConfig对象,然后在BootStrap的init方法中,有这样的过程

@Override
@SuppressWarnings("unchecked")
void init(Channel channel) throws Exception {
	ChannelPipeline p = channel.pipeline();
	......
	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);
			}
		}
	}

	......
}

我们看到,它遍历channe的options,然后通过config对象的setOption去设置config中的属性,如DefaultChannelConfig中

    @Override
    @SuppressWarnings("deprecation")
    public <T> boolean setOption(ChannelOption<T> option, T value) {
        validate(option, value);

        if (option == CONNECT_TIMEOUT_MILLIS) {
            setConnectTimeoutMillis((Integer) value);
        } else if (option == MAX_MESSAGES_PER_READ) {
            setMaxMessagesPerRead((Integer) value);
        } else if (option == WRITE_SPIN_COUNT) {
            setWriteSpinCount((Integer) value);
        } else if (option == ALLOCATOR) {
            setAllocator((ByteBufAllocator) value);
        } else if (option == RCVBUF_ALLOCATOR) {
            setRecvByteBufAllocator((RecvByteBufAllocator) value);
        } else if (option == AUTO_READ) {
            setAutoRead((Boolean) value);
        } else if (option == AUTO_CLOSE) {
            setAutoClose((Boolean) value);
        } else if (option == WRITE_BUFFER_HIGH_WATER_MARK) {
            setWriteBufferHighWaterMark((Integer) value);
        } else if (option == WRITE_BUFFER_LOW_WATER_MARK) {
            setWriteBufferLowWaterMark((Integer) value);
        } else if (option == MESSAGE_SIZE_ESTIMATOR) {
            setMessageSizeEstimator((MessageSizeEstimator) value);
        } else {
            return false;
        }

        return true;
    }

DefaultSocketChannelConfig中道理一样。

NioSocketChannelConfig的继承关系如下

NioSocketChannelConfig extends DefaultSocketChannelConfig extends DefaultChannelConfig implements ChannelConfig

DefaultChannelConfig中是一般性的选项,NioSocketChannelConfig是与socket相关的设置,ChannelOption中以SO开头的都是与此相关的。
使用相关option时,也是通过config的getOption去获取的。当然Config对象也设置了一些属性,和这些option相关联,可以通过方法直接访问到。

    public <T> T getOption(ChannelOption<T> option) {
        if (option == null) {
            throw new NullPointerException("option");
        }

        if (option == CONNECT_TIMEOUT_MILLIS) {
            return (T) Integer.valueOf(getConnectTimeoutMillis());
        }
        ......
        return null;
    }

比如我们设置超时时间ChannelOption.CONNECT_TIMEOUT_MILLIS,那么在AbstractNioChannel的connect方法中就能看到它的踪影:

        public final void connect(
            ......
            try {
                ......
                boolean wasActive = isActive();
                if (doConnect(remoteAddress, localAddress)) {
                    fulfillConnectPromise(promise, wasActive);
                } else {
                    connectPromise = promise;
                    requestedRemoteAddress = remoteAddress;

                    // Schedule connect timeout.
                    int connectTimeoutMillis = config().getConnectTimeoutMillis();
                    if (connectTimeoutMillis > 0) {
                        connectTimeoutFuture = eventLoop().schedule(new OneTimeTask() {
                            @Override
                            public void run() {
                                ChannelPromise connectPromise = AbstractNioChannel.this.connectPromise;
                                ConnectTimeoutException cause =
                                        new ConnectTimeoutException("connection timed out: " + remoteAddress);
                                if (connectPromise != null && connectPromise.tryFailure(cause)) {
                                    close(voidPromise());
                                }
                            }
                        }, connectTimeoutMillis, TimeUnit.MILLISECONDS);
                    }
                    ......
                }
            } catch (Throwable t) {
                promise.tryFailure(annotateConnectException(t, remoteAddress));
                closeIfClosed();
            }
        }

config().getConnectTimeoutMillis()获取设置,然后启动定时任务,等待超时。

时间: 2024-12-30 04:48:00

Netty:options和configs的相关文章

_00019 Storm的体系结构介绍以及Storm入门案例(官网上的简单Java案例)

博文作者:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前,妳却感觉不到我的存在 技术方向:Flume+Kafka+Storm+Redis/Hbase+Hadoop+Hive+Mahout+Spark ... 云计算技术 转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作! qq交流群:214293307  (期待与你一起学习,共同进步) # Storm

单个jetty 8.1.17跑多个应用的分析过程(分别用独立端口独立进程)

一.搭建测试环境: ####系统版本信息####CentOS release 6.7 (Final) ############################系统内核版本#####Linux version 2.6.32-573.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) ) #1 SMP Thu Jul 23 15:44:03 UTC 2015 ####jetty版本号#

一,Jetty启动

一,Jetty安装 从官网download.eclipse.org/jetty/ 下载需要的版本,在指定目录解压即可,下面用$JETTY_HOME表示Jetty的解压目录,也就是安装目录.我用的版本是9.2.6.v20141205. 二,Jetty启动 1,jetty.sh脚本启动 在目录$JETTY_HOME/bin目录下有脚本文件jetty.sh,输入 jetty.sh start 即可启动Jetty,在浏览器中输入localhost:8080/可得到Jetty的主页.默认情况下是为空的,可

Jetty初探

一.在jetty中部署web应用 Jetty 和 Tomcat 一样都是一个web server的container, 用户可以在里面 deploy 自己的 war 包,然后启动 Jetty, 进而通过浏览器去访问你的 web content. 从jetty官网下载jetty 9的压缩包,并解压到本地.假设jetty的路径是D:\jetty-9, 在CMD里运行 > cd D:\jetty-9\demo-base > java -jar ..\start.jar 2015-06-04 10:5

[李景山php]每天laravel-20161119|Connector.php

<?php namespace Illuminate\Database\Connectors; use PDO; use Exception; use Illuminate\Support\Arr; use Illuminate\Database\DetectsLostConnections; // that was system class class Connector {// a connector     use DetectsLostConnections;// a trait lik

Jetty学习一:基本功能介绍

Jetty是一个开源项目,提供了HTTP Server,HTTP Client和Javax.servlet容器,这里(http://www.eclipse.org/jetty/)是它的官方网站,这里对它做一个基本的介绍,包括基本目录.启动方式和应用部署. Jetty目录结构 下面是Jetty 9.10的发布版本包含的文件和文件夹,及其作用. license-eplv10-aslv20.html Jetty的License文件 README.txt Jetty的基本信息和命令 VERSION.tx

数学之路-分布式计算-storm(3)

5.安装zookeeper 本博客全部内容是原创.假设转载请注明来源 http://blog.csdn.net/myhaspl/ [email protected]:~/jzmq-master$cd .. [email protected]:~$wget http://apache.fayea.com/zookeeper/zookeeper-3.3.6/zookeeper-3.3.6.tar.gz [email protected]:~$tar -xzvf zookeeper-3.3.6.tar

ToolKit与jQuery类似的前端插件

优点: 丢弃了一些不常用的方法(jQuery.fn):slideUp.fadeIn.animate等: 新增获取子节点的方法(ToolKit.fn):firstChild,lastChild等: 新增ToolKit.Threads线程操作函数(有效解决自定义弹窗同时运行的问题): 加入JSON对象(JSON.parse和JSON.stringify); 重写ToolKit.toString方法为JSON.stringify,ToolKit.get和ToolKit.post的dataType为js

Jetty使用教程(一)——开始使用Jetty

一.Jetty简介 1.1 什么是Jetty Jetty是一个提供HHTP服务器.HTTP客户端和javax.servlet容器的开源项目. 这个入门教程分为五个部分: 第一部分部分重点介绍如何使用Jetty,它提供如下信息,如什么是Jetty,从哪可以下载它,怎么在像Maven一样的仓库中找到它.这一部分同样会提供启动Jetty和如何配置Jetty的快速入门. 第二部分从更细致的方面介绍Jetty的配置,介绍怎么用Jetty来部署一个web应用程序,怎么配置容器和连接,以及如何实现SSL和其它