package com.zengweidaren.demo1.netty.source.echo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.SelfSignedCertificate; public final class EchoServer { static final boolean SSL = System.getProperty("ssl") != null; static final int PORT = Integer.parseInt(System.getProperty("port", "8009")); public static void main(String[] args) throws Exception { final SslContext sslCtx; if (SSL) { SelfSignedCertificate ssc = new SelfSignedCertificate(); sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); } else { sslCtx = null; } EventLoopGroup bossGroup = new NioEventLoopGroup(1); //1 EventLoopGroup workerGroup = new NioEventLoopGroup(); try { //2 ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup)//2.1 .channel(NioServerSocketChannel.class)//2.2 .option(ChannelOption.SO_BACKLOG, 100) .handler(new LoggingHandler(LogLevel.INFO))//2.3 .childHandler(new ChannelInitializer<SocketChannel>() {//2.4 @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); } p.addLast(new LoggingHandler(LogLevel.INFO)); //p.addLast(new EchoServerHandler()); } }); ChannelFuture f = b.bind(PORT).sync();//2.5 f.channel().closeFuture().sync();//2.6 } finally { //2.7 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
1.1、当EventLoopGroup workerGroup = new NioEventLoopGroup();
执行时,会调用
DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
"io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
,创建线程根据默认个线程 cpu 核数*2,可以充分的利用多核的优势。
1.2、调用多线程事件循环器
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args)
会创建, EventExecutor 数组 :EventExecutor[] children = new EventExecutor[nThreads];
EventExecutor 数组中的每一个元素都是NIOEventLoop,NIOEventLoop 实现了 EventLoop 接口 和 Executor 接口
1.3、遍历事件执行器,将每一个都添加一个监听器
for (EventExecutor e: children) {
e.terminationFuture().addListener(terminationListener);
}
将EventExecutor 最后放入一个叫readonlyChildern的父类是Collections集合中
返回的workerCroup中包含:ExentExcetor,Collections,Atomiclnteger,DefaultPromise,DefalitEventExecutorChooseFactory
2.1、
ServerBootstrap 对象,他是一个引导类,用于启动服务器和引导整个程序的初始化
它和 ServerChannel 关联, 而 ServerChannel 继承了 Channel,有一些方法 remoteAddress 等
2.2.channel(NioServersSocketChannel.classs),通过添加了一个 channel , 其中参数一个 Class 对象, 引导类将通过这个 Class 对象反射创建
ChannelFactory。然后添加了一些 TCP 的参数。[说明:Channel 的创建在bind 方法,可以 Debug 下 bind ,会找到 channel = channelFactory.newChannel();
2.3: .handler(new LoggingHandler(LogLevel.INFO))再添加了一个服务器专属的日志处理器 handler。
2.4:childHandler(new ChannelInitializer<SocketChannel>() {@Override
public void initChannel(SocketChannel ch) throws Exception {.......}
再添加一个 SocketChannel(不是 ServerSocketChannel)的 handler
2.5ChannelFuture f = b.bind(PORT).sync();然后绑定端口并阻塞至连接成功。
2.6f.channel().closeFuture().sync();最后 main 线程阻塞等待关闭。
2.7bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();finally 块中的代码将在服务器关闭时优雅关闭所有资源