Netty quick start

Posted by coder500 on Mon, 10 Jan 2022 23:36:21 +0100

This article mainly introduces how to learn and know Netty quickly. You can also understand it as learning introduction and quick start. It is strongly recommended that you collect this article for future reference.

Netty

netty It is a high-performance, elastic and extensible asynchronous event driven network application framework based on NIO model. You can use her to quickly develop stable and flexible client and server applications. Please see the official introduction here .

Architecture

Before starting, let's take a look at the overall architecture of the technology (if you don't like this section, you can skip [get start])
netty architecture

Core components

The core components of netty will be listed here. Of course, due to space problems, I won't explain them too much

ByteBuf

io.netty.buffer.ByteBuf It is a binary data storage component customized by netty, with similar functions java.nio.ByteBuffer However, it makes it easier for users to use.

readerIndex & writerIndex

As shown in the figure, ByteBuf defines readerindex & writerindex to facilitate reading and writing to ByteBuf.

CompositeByteBuf

CompositeByteBuf It is a virtual buffer that presents multiple buffers as a simple merged buffer. This is very practical when multiple buffers need to synthesize one buffer (reduce memory copy).

Channel

io.netty.channel A component connected to a network socket or capable of I/O operations such as read, write, connect, and bind.

Common implementation classes

  1. NioSocketChannel client NIO selector implementation
  2. NioServerSocketChannel server NIO selector implementation

ChannelPipeline

io.netty.channel.ChannelPipeline The ChannelHandler List pattern is designed to handle or intercept inbound events and outbound operations of the Channel. The processing sequence is as follows:

ChannelHandler

io.netty.channel.ChannelHandler IO event processor is the most frequently used interface. In order to implement our own business logic, we must add our own processor to the pipeline.

ChannelHandler inbound & outbound processing

  1. ChannelInboundHandler inbound processing. The ChannelInboundHandlerAdapter adaptation class is generally used during use
  2. ChannelOutboundHandler outbound processing. The ChannelOutboundHandlerAdapter adaptation class is generally used during use

EventLoop

io.netty.channel.EventLoop It is responsible for processing one or more channels, and each EventLoop will bind a Thread.
NioEventLoopGroup is commonly used, which is the EventLoopGroup implementation class and the EventLoop collection in NIO model.

Getting Started

Finally to this section, this section will write a simple DEMO. Relevant instructions are also annotated in the code. For more detailed description, please refer to here

Echo Server

public class NettyEchoServerDemo {
    public static void main(String[] args) throws Exception {
        //Multithreaded event processor, default to current number of cores * 2
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //Startup class
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)// nio socketchannel
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            //Add application, data handler, ChannelHandler
                            ch.pipeline().addLast(new EchoChannelHandler());
                        }
                    })
                    //option is used to set NioServerSocketChannel
                    .option(ChannelOption.SO_BACKLOG, 128)
                    //childOption is used to set the acquired Channel, that is, NioSocketChannel
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            // Bind and start to accept incoming connections.
            ChannelFuture f = b.bind(7).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    //Customize a ChannelInboundHandler 
    public static class EchoChannelHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ctx.write(msg);
            ctx.flush();
        }
    }
}
Copy code

Echo Client

public class NettyEchoClientDemo {
    public static void main(String[] args) throws Exception {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //client startup class
            Bootstrap b = new Bootstrap();
            b.group(workerGroup)
                    //SocketChannel
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() { // (4)
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            //Custom data handler ChannelHandler
                            ch.pipeline().addLast(new EchoChannelHandler());
                        }
                    })
                    .option(ChannelOption.SO_KEEPALIVE, true);
            //Establish connection
            ChannelFuture f = b.connect("127.0.0.1",7).syncUninterruptibly(); // (7)
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
    //Customize ChannelInboundHandler
    public static class EchoChannelHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            System.out.println(((ByteBuf)msg).toString(CharsetUtil.UTF_8));
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            //Interaction with server
            String name = bufferedReader.readLine();
            System.out.println(name);
            ctx.writeAndFlush(Unpooled.copiedBuffer(name.getBytes()));
        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            super.channelActive(ctx);
            //For the first time, send a message to the server, where ByteBuf needs to be sent
            ChannelFuture c = ctx.writeAndFlush(Unpooled.copiedBuffer("message".getBytes()));
            if(!c.isSuccess()){
                System.out.println(c.cause());
            }
        }
    }
}
Copy code

thank


 

Topics: Java Netty Back-end Programmer architecture