1. Introduction to Netty
Netty is a java open source network communication framework provided by JBOSS. Netty is a network application framework based on Java NIO client-server. Using Netty, you can quickly develop network applications, such as server and client protocols. Netty provides a new way to develop web applications that makes it easy to use and highly extensible. Netty's internal implementation is complex, but Netty provides an easy-to-use API to decouple business logic from network processing code. Netty is completely implemented based on NIO, so the entire Netty is asynchronous.
Advantages of netty
Its robustness, functionality, performance, customizability and extensibility are second to none in its class. It has been verified by hundreds of commercial/commercial projects, such as Hadoop's RPC framework Avro, RocketMQ and mainstream distributed communication framework Dubbox, etc.
2. Getting started with Hello World
1. Steps of Netty communication:
①Create two NIO thread groups, one for network event processing (accepting client connections), and the other for reading and writing network communications.
②Create a ServerBootstrap object and configure a series of parameters of Netty , such as the cache size for accepting outgoing data, etc.
③ Create a class ChannelInitializer that is used to actually process data, and prepare for initialization, such as setting the character set, format and interface for actually processing data that accepts outgoing data.
④Bind the port, execute the synchronous blocking method and wait for the server to start.
2. Introductory example (take helloworld as an example)
2.1 Download the corresponding jar package
You can go to http://netty.io/ to download the required Netty package
The jar package I use is https://pan.baidu.com/s/1tm2EgYtDpTS5dejVnHhvPw Password: vc8b
2.2 Code Implementation
Service-Terminal
package com.xyq.netty.hello; 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; public class Server { public static void main(String[] args) throws Exception { //1 Create two thread groups EventLoopGroup pGroup = new NioEventLoopGroup();//One is used to process server-side receiving client connections EventLoopGroup cGroup = new NioEventLoopGroup();//One is for network communication (network read and write) //2 Create an auxiliary tool class for a series of configurations of the server channel ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(pGroup, cGroup)//Bind two thread groups .channel(NioServerSocketChannel.class)//Specify the mode of NIO .option(ChannelOption.SO_BACKLOG, 1024)//Set tcp buffer .option(ChannelOption.SO_SNDBUF, 32*1024)//Set the send buffer size .option(ChannelOption.SO_RCVBUF, 32*1024)//Set the receive buffer size .option(ChannelOption.SO_KEEPALIVE, true)//Keep connected .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { //3 Configure the processing of specific data receiving methods here ch.pipeline().addLast(new ServerHandler()); } }); //4 to bind ChannelFuture cf = bootstrap.bind(8765).sync(); System.out.println("server start ..."); //5 wait for shutdown cf.channel().closeFuture().sync(); pGroup.shutdownGracefully(); cGroup.shutdownGracefully(); } }
Server management class
package com.xyq.netty.hello; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; public class ServerHandler extends ChannelHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //Read the information sent by the client ByteBuf buf = (ByteBuf) msg; byte[] bs = new byte[buf.readableBytes()]; buf.readBytes(bs); String body = new String(bs, "utf-8"); System.out.println("The data received by the server is " + body); // respond to the client String result = "The server has received the message, the message is " + body; ctx.writeAndFlush(Unpooled.copiedBuffer(result.getBytes())); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
client
package com.xyq.netty.hello; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; public class Client { public static void main(String[] args)throws Exception { //1 Create a thread group EventLoopGroup group = new NioEventLoopGroup(); //2 Create an auxiliary tool class for a series of configurations of the server channel Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group)//Bind thread group .channel(NioSocketChannel.class)//Specify the mode of NIO .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { //3 Configure the processing of specific data receiving methods here ch.pipeline().addLast(new ClientHandler()); } }); //4 make the connection ChannelFuture future = bootstrap.connect("127.0.0.1", 8765).sync(); System.out.println("Client connect...."); //5 send message future.channel().writeAndFlush(Unpooled.copiedBuffer("你好".getBytes())); Thread.sleep(1000); future.channel().writeAndFlush(Unpooled.copiedBuffer("世界".getBytes())); Thread.sleep(1000); future.channel().writeAndFlush(Unpooled.copiedBuffer("!".getBytes())); //6 wait for shutdown future.channel().closeFuture().sync(); group.shutdownGracefully(); } }
Client management class
package com.xyq.netty.hello; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.util.ReferenceCountUtil; public class ClientHandler extends ChannelHandlerAdapter{ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try { //Read the information sent by the server ByteBuf buf = (ByteBuf) msg; byte[] bs = new byte[buf.readableBytes()]; buf.readBytes(bs); String body = new String(bs, "utf-8"); System.out.println("The client received the response message from the server" + body); } finally{ ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }