Netty learning: build a simple Netty service

Netty learning: build a simple Netty service

Netty is an asynchronous communication framework based on JAVA NIO class library. Its architectural features are: asynchronous non-blocking, event-driven, high performance, high reliability and high customizability. In other words, Netty is a NIO framework that makes it easy and fast to develop network applications, such as client and server protocols. Netty greatly simplifies the development process of network programs, such as the development of Sockets for TCP and UDP. Netty has gradually become the framework of choice for Java NIO programming.

Project official address: http://netty.io/index.html

1. Advantages of Netty:

  • The API is easy to use, and the development threshold is low;
  • Powerful, preset a variety of codec functions, support a variety of mainstream protocols;
  • Strong customization ability, the communication framework can be flexibly extended through ChannelHandler;
  • High performance, compared with other mainstream NIO frameworks in the industry, Netty has the best overall performance;
  • The community is active, the version iteration cycle is short, the bugs found can be fixed in time, and more new functions will be added;
  • After a large-scale commercial application test, the quality has been verified. It has been successfully commercialized in many industries such as the Internet, big data, online games, enterprise applications, and telecommunication software, which proves that it fully meets the commercial standards of different industries.

2. Build Netty service:

  1. add pom dependencies
    <dependency>
    	<groupId>io.netty</groupId>
    	<artifactId>netty-all</artifactId>
    	<version>4.1.0.Final</version>
    </dependency>
     
  2. SimpleServer (server)
    package com.yingjun.netty.server;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    /**
     *
     * In Netty, after the two parties of the communication establish a connection, the data will be transmitted in the way of ByteBuf.
     * For example, in the http protocol, the ByteBuf data stream is processed through the HttpRequestDecoder and converted into an http object.
     *
     */
    public class SimpleServer {
    	private int port;
    
    	public SimpleServer(int port) {
    		this.port = port;
    	}
    
    	public void run() throws Exception {
    		//EventLoopGroup is a multi-threaded event looper used to handle IO operations
    		//bossGroup is used to receive incoming connections
    		EventLoopGroup bossGroup = new NioEventLoopGroup();
    		//workerGroup is used to handle connections that have been received
    		EventLoopGroup workerGroup = new NioEventLoopGroup();
    		try {
    			//Auxiliary startup class to start NIO service
    			ServerBootstrap b = new ServerBootstrap();
    			b.group(bossGroup, workerGroup)
    				//Configure Channel
    				.channel(NioServerSocketChannel.class)
    				.childHandler(new ChannelInitializer<SocketChannel>() {
    						@Override
    						public void initChannel(SocketChannel ch) throws Exception {
    							// register handler  
    							ch.pipeline().addLast(new SimpleServerHandler());
    						}
    					})
    				.option(ChannelOption.SO_BACKLOG, 128)
    				.childOption(ChannelOption.SO_KEEPALIVE, true);
    
    			// Bind the port and start receiving incoming connections
    			ChannelFuture f = b.bind(port).sync();
    			// Wait for the server socket to close.
    			f.channel().closeFuture().sync();
    		} finally {
    			workerGroup.shutdownGracefully();
    			bossGroup.shutdownGracefully();
    		}
    	}
    	
    	public static void main(String[] args) throws Exception {
            new SimpleServer(9999).run();
        }
    }
    
     
  3. SimpleServerHandler (server request processing Handler)
    package com.yingjun.netty.server;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    public class SimpleServerHandler extends ChannelInboundHandlerAdapter {
    
    	@Override
    	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    		System.out.println("SimpleServerHandler.channelRead");
    		ByteBuf result = (ByteBuf) msg;
    		byte[] result1 = new byte[result.readableBytes()];
    		// msg stores data of type ByteBuf, and reads the data into byte[]
    		result.readBytes(result1);
    		String resultStr = new String(result1);
    		// Receive and print client information
    		System.out.println("Client said:" + resultStr);
    		// Release resources, this line is critical
    		result.release();
    
    		// send message to client
    		String response = "hello client!";
    		// In the current scenario, the sent data must be converted into a ByteBuf array
    		ByteBuf encoded = ctx.alloc().buffer(4 * response.length());
    		encoded.writeBytes(response.getBytes());
    		ctx.write(encoded);
    		ctx.flush();
    	}
    
    	@Override
    	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    		// close the connection when an exception occurs
    		cause.printStackTrace();
    		ctx.close();
    	}
    
    	@Override
    	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    		ctx.flush();
    	}
    
    }
    
     
  4. SimpleServer (client)
    package com.yingjun.netty.server;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    public class SimpleClient {
    	
    	public void connect(String host, int port) throws Exception {
    		EventLoopGroup workerGroup = new NioEventLoopGroup();
    
    		try {
    			Bootstrap b = new Bootstrap();
    			b.group(workerGroup);
    			b.channel(NioSocketChannel.class);
    			b.option(ChannelOption.SO_KEEPALIVE, true);
    			b.handler(new ChannelInitializer<SocketChannel>() {
    				@Override
    				public void initChannel(SocketChannel ch) throws Exception {
    					ch.pipeline().addLast(new SimpleClientHandler());
    				}
    			});
    
    			// Start the client.
    			ChannelFuture f = b.connect(host, port).sync();
    
    			// Wait until the connection is closed.
    			f.channel().closeFuture().sync();
    		} finally {
    			workerGroup.shutdownGracefully();
    		}
    	}
    	
    	public static void main(String[] args) throws Exception {
    		SimpleClient client=new SimpleClient();
    		client.connect("127.0.0.1", 9999);
    	}
    	
    }
    
     
  5. SimpleServerHandler (client request processing Handler)
    package com.yingjun.netty.server;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    public class SimpleClientHandler extends ChannelInboundHandlerAdapter {
    
    	@Override
    	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    		System.out.println("SimpleClientHandler.channelRead");  
            ByteBuf result = (ByteBuf) msg;  
            byte[] result1 = new byte[result.readableBytes()];  
            result.readBytes(result1);  
            System.out.println("Server said:" + new String(result1));  
            result.release();  
    	}
    
    	@Override
    	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    		// close the connection when an exception occurs
    		cause.printStackTrace();
    		ctx.close();
    	}
    
    	
    	// After the connection is successful, send a message to the server  
        @Override  
        public void channelActive(ChannelHandlerContext ctx) throws Exception {  
        	String msg = "hello Server!";  
            ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());  
            encoded.writeBytes(msg.getBytes());  
            ctx.write(encoded);  
            ctx.flush();  
        }  
    }
    
     
  6. operation result:

    SimpleClientHandler.channelRead
    Server said:hello client!
    ------------------------------------------
    SimpleServerHandler.channelRead
    Client said:hello Server!
    SimpleServerHandler.channelRead
    Client said:hello Server!
     

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326859013&siteId=291194637