In this article, we will use a simple example to learn the basics of netty programming.

The requirement is simple: the client sends a message to the server, the server receives the message, prints it, and replies to the client, ending the communication once.

Start by writing a server-side processing handle

public class ServerExampleHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client connect");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client close");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println(msg);
        ctx.channel().writeAndFlush("hello I am server"); }}Copy the code

The three methods correspond to connection open, connection close, and message receive events respectively.

The server code is as follows:

public class NettyServer {

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup boss = new NioEventLoopGroup(1);
        EventLoopGroup worker = new NioEventLoopGroup(8);

        ServerBootstrap b = new ServerBootstrap();
        try {

            b.group(boss, worker)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<NioSocketChannel>() {
                 @Override
                 protected void initChannel(NioSocketChannel ch) throws Exception {
                     //这两个handle为netty自带的
                     ch.pipeline().addLast(new StringDecoder());
                     ch.pipeline().addLast(new StringEncoder());
                     //这是实现我们自定义逻辑的handle
                     ch.pipeline().addLast(new ServerExampleHandler());
                 }
             });
            b.bind(8080).channel().closeFuture().sync();
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

}
Copy the code

Secondly, write the client to process handle

public class ClientExampleHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush("I am client"); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println(msg); ctx.close(); }}Copy the code

The client code is as follows:

public class NettyClient { public static void main(String[] args) throws InterruptedException { EventLoopGroup group = new NioEventLoopGroup(1); Bootstrap b = new Bootstrap(); try { b.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<NioSocketChannel>() { @Override Protected void initChannel(NioSocketChannel ch) throws Exception {// The two handles are netty's own ch.pipeline().addlast (new) StringDecoder()); ch.pipeline().addLast(new StringEncoder()); // This is the handle ch.pipeline().addlast (new ClientExampleHandler()) that implements our custom logic; }}); b.connect("127.0.0.1", 8080).channel().closeFuture().sync(); } finally { group.shutdownGracefully(); }}}Copy the code

Such a function of server and client to communicate with each other has been realized.

In fact, in the above netTY programming, our own logic is mainly two Handles, and the other codes belong to the Netty framework. In contrast to JDK code, netty programming clearly allows us to focus more on business logic.

So what does Netty do for us? All changes are the same, IO programming two steps

  1. Receives the connection
  2. Process the message

The same goes for Netty. Let’s take a look at how Netty accomplishes these two steps.