1.Netty源码分析一

Echo例子

Echo Client

public final class EchoClient {  
  
    static final String HOST = System.getProperty("host", "127.0.0.1");  
    static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));  
    static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));  
  
    public static void main(String[] args) throws Exception {  
        // Configure SSL.git  
        final SslContext sslCtx = ServerUtil.buildSslContext();  
  
        // Configure the client.  
        EventLoopGroup group = new NioEventLoopGroup();  
        try {  
            Bootstrap b = new Bootstrap();  
            b.group(group)  
             .channel(NioSocketChannel.class)  
             .option(ChannelOption.TCP_NODELAY, true)  
             .handler(new ChannelInitializer<SocketChannel>() {  
                 @Override  
                 public void initChannel(SocketChannel ch) throws Exception {  
                     ChannelPipeline p = ch.pipeline();  
                     if (sslCtx != null) {  
                         p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));  
                     }  
                     //p.addLast(new LoggingHandler(LogLevel.INFO));  
                     p.addLast(new EchoClientHandler());  
                 }  
             });  
  
            // Start the client.  
            ChannelFuture f = b.connect(HOST, PORT).sync();  
  
            // Wait until the connection is closed.  
            f.channel().closeFuture().sync();  
        } finally {  
            // Shut down the event loop to terminate all threads.  
            group.shutdownGracefully();  
        }  
    }  
}

EchoServer

public final class EchoServer {  
  
    static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));  
  
    public static void main(String[] args) throws Exception {  
        // Configure SSL.  
        final SslContext sslCtx = ServerUtil.buildSslContext();  
  
        // Configure the server.  
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);  
        EventLoopGroup workerGroup = new NioEventLoopGroup();  
        final EchoServerHandler serverHandler = new EchoServerHandler();  
        try {  
            ServerBootstrap b = new ServerBootstrap();  
            b.group(bossGroup, workerGroup)  
             .channel(NioServerSocketChannel.class)  
             .option(ChannelOption.SO_BACKLOG, 100)  
             .handler(new LoggingHandler(LogLevel.INFO))  
             .childHandler(new ChannelInitializer<SocketChannel>() {  
                 @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(serverHandler);  
                 }  
             });  
  
            // Start the server.  
            ChannelFuture f = b.bind(PORT).sync();  
  
            // Wait until the server socket is closed.  
            f.channel().closeFuture().sync();  
        } finally {  
            // Shut down all event loops to terminate all threads.  
            bossGroup.shutdownGracefully();  
            workerGroup.shutdownGracefully();  
        }  
    }  
}

在实际应用中,上述代码基本就是开发模板,唯一需要开发者做的就是自定义实现各种Handler,例如上述代码中的EchoClientHandler和EchoServerHandler。

public class EchoClientHandler extends ChannelInboundHandlerAdapter {  
  
    private final ByteBuf firstMessage;  
  
    /**  
     * Creates a client-side handler.     */    public EchoClientHandler() {  
        firstMessage = Unpooled.buffer(EchoClient.SIZE);  
        for (int i = 0; i < firstMessage.capacity(); i ++) {  
            firstMessage.writeByte((byte) i);  
        }  
    }  
  
    @Override  
    public void channelActive(ChannelHandlerContext ctx) {  
        ctx.writeAndFlush(firstMessage);  
    }  
  
    @Override  
    public void channelRead(ChannelHandlerContext ctx, Object msg) {  
        ctx.write(msg);  
    }  
  
    @Override  
    public void channelReadComplete(ChannelHandlerContext ctx) {  
       ctx.flush();  
    }  
  
    @Override  
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
        // Close the connection when an exception is raised.  
        cause.printStackTrace();  
        ctx.close();  
    }  
}

针对上述代码部分组件介绍: