Netty source code practice
To learn netty, you can start from the netty-example module of netty source code.
netty-example has an example echo, which is very suitable for introductory learning.
Here it is slightly modified and used as an example for learning.
Introduce dependency packages:
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.29.Final</version> </dependency>
Server
After receiving the client’s message, the server will respond.
- EchoServer:
/** * After receiving the client's message, the server will respond. */ public final class EchoServer { /** * port */ static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); public static void main(String[] args) throws Exception { //Configure EventLoopGroup // Master-slave Reactor multi-thread mode, bossGroup is the master Reactor, workerGroup is the slave Reactor EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { //Initialize the server's boot class ServerBootstrap ServerBootstrap serverBootstrap = new ServerBootstrap(); //Specify EventLoopGroup serverBootstrap.group(bossGroup, workerGroup) //Specify channel .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 100) //Specify ChannelHandler for processing channel .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { //ChannelPipeline, based on the responsibility chain model, can add multiple ChannelHandlers ChannelPipeline channelPipeline = ch.pipeline(); //channelPipeline.addLast(new LoggingHandler(LogLevel.INFO)); //ChannelHandler, used to process channels, process received data, and implement business logic. channelPipeline.addLast(new EchoServerHandler()); } }); // Start the server and bind the server to the port on which it will listen for connection requests. ChannelFuture channelFuture = serverBootstrap.bind(PORT).sync(); // Wait until the server socket is closed channelFuture.channel().closeFuture().sync(); } finally { //Close all eventLoops and terminate threads bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
- EchoServerHandler:
ChannelHandler is used to process channels and implement business logic.
/** * ChannelHandler on the server side. * * ChannelHandler, used to process channels, process received data, and implement business logic. * Inherit ChannelInboundHandlerAdapter to define methods for responding to inbound events. * */ @Sharable public class EchoServerHandler extends ChannelInboundHandlerAdapter { /** * channelRead(): Read the message passed in by channel * */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf buf= (ByteBuf) msg; log.info("Message from client: " + buf.toString(CharsetUtil.UTF_8) + "\ "); } /** * channelReadComplete(): Indicates that the current ChannelHandler has finished reading. * After execution, it will automatically jump to the next ChannelHandler in ChannelPipeline. * */ @Override public void channelReadComplete(ChannelHandlerContext ctx) { //Return data to the client, writeAndFlush() can also be split into write(msg) and flush() ctx.writeAndFlush(Unpooled.copiedBuffer("I'm happy to see you too^_^",CharsetUtil.UTF_8)); } /** * exceptionCaught(): Called when an exception is thrown during the read operation. * */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { //Close the connection when an exception occurs cause.printStackTrace(); ctx.close(); } }
Client
In the following example, the client sends a message to the server.
- EchoClient:
/** * client. Send data to the server and receive the response from the server. * */ 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 { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline channelPipeline = socketChannel.pipeline(); //channelPipeline.addLast(new LoggingHandler(LogLevel.INFO)); //ChannelHandler, used to process channels, process received data, and implement business logic. channelPipeline.addLast(new EchoClientHandler()); } }); //Open the client and connect to the port of the server ChannelFuture channelFuture = bootstrap.connect(HOST, PORT).sync(); channelFuture.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } }
- EchoClientHandler:
/** * Client's ChannelHandler. */ public class EchoClientHandler extends ChannelInboundHandlerAdapter { /** * channelActive() will be called after the connection between the client and the server is established. * */ @Override public void channelActive(ChannelHandlerContext ctx) { ByteBuf firstMessage = Unpooled.buffer(EchoClient.SIZE); byte[] bytes = "Nice to meet you^_^\ ".getBytes(CharsetUtil.UTF_8); firstMessage.writeBytes(bytes); //Send data to server ctx.writeAndFlush(firstMessage); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf buf = (ByteBuf) msg; log.info("Message from the server: " + buf.toString(CharsetUtil.UTF_8)); } @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
Execution:
Start the server first, then the client.
The server receives information from the client:
11:25:03.081 [nioEventLoopGroup-3-1] INFO com.example.demo.netty.echo.EchoServerHandler - Message from client: Nice to meet you^_^
The client receives the reply from the server:
11:25:03.091 [nioEventLoopGroup-2-1] INFO com.example.demo.netty.echo.EchoClientHandler - Message from the server: I am also very happy to meet you^_^
Netty common classes
The above example uses Netty’s commonly used classes.
For details, see: https://blog.csdn.net/sinat_32502451/article/details/133934402
Reference materials:
https://zhuanlan.zhihu.com/p/415450910