Netty (1) -- Netty Entry Program, netty Entry Program

Source: Internet
Author: User

Netty (1) -- Netty Entry Program, netty Entry Program

Reprinted please indicate the source: http://www.cnblogs.com/Joanna-Yan/p/7447618.html

If you are interested, you can first understand the comparison and selection of four I/O types.

The main content includes:

  • Setting up the Netty Development Environment
  • Server application TimeServer Development
  • Client Program TimeClient Development
  • Time Server Running and debugging
1. Set up the Netty Development Environment

Prerequisites: JDK 1.7 has been installed on the computer and the JDK environment variable path has been configured.

Download the latest Netty installation package from the Netty website and decompress it.

At this time we will find that it contains the various modules of the. jar package and source code, because we directly use the binary class library Netty, so only need to netty-all-4.1.15.Final.jar.

Create a Java project and introduce netty-all-4.1.15.Final.jar.

2. Netty server development

Before using Netty to develop TimeServer, let's review the process of using NIO for server development.

A simple NIO server program, if we need to directly use the jdk nio class library for development, requires more than 10 complex operations to complete the most basic message reading and sending, this is why we chose Netty and other NIO frameworks. Let's take a look at how Netty can be easily developed on the server.

Package joanna. yan. netty; 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 TimeServer {p Ublic static void main (String [] args) throws Exception {int port = 9090; if (args! = Null & args. length> 0) {try {port = Integer. valueOf (args [0]);} catch (Exception e) {// use the default value} new TimeServer (). bind (port);} public void bind (int port) throws Exception {/** configure the NIO thread group of the server, which contains a group of NIO threads, specifically used for processing network events. They are actually Reactor thread groups. * Two reasons are created: one for the server to accept client connections, and the other for network read/write of SocketChannel. */EventLoopGroup bossGroup = new NioEventLoopGroup (); EventLoopGroup workerGroup = new NioEventLoopGroup (); try {// ServerBootstrap object. Netty is used to start the auxiliary startup class of the NIO server, the objective is to reduce the development complexity of the server. ServerBootstrap B = new ServerBootstrap (); B. group (bossGroup, workerGroup ). channel (NioServerSocketChannel. class ). option (ChannelOption. SO_BACKLOG, 1024)/** ChildChannelHandler, the processing class for binding I/O events, which is similar to the handler class in Reactor mode. * It is mainly used to process network I/O events, for example: record logs and CODEC messages. */. ChildHandler (new ChildChannelHandler ();/** bind the port and wait for synchronization to succeed (call its bind method to bind the listening port. Then, call its synchronous blocking method sync to wait until the binding operation is completed. * After completion, Netty returns a ChannelFuture, which is similar to java. util. concurrent. Future of JDK. * It is mainly used for notification callback of asynchronous operations .) */ChannelFuture f = B. bind (port ). sync (); // wait until the server listening port is closed (use f. channel (). closeFuture (). the sync () method is blocked and the main function exits after the server link is closed .) F. channel (). closeFuture (). sync ();} finally {// exit gracefully, releasing the thread pool resource bossGroup. shutdownGracefully (); workerGroup. shutdownGracefully () ;}} private class ChildChannelHandler extends ChannelInitializer <SocketChannel >{@ Override protected void initChannel (SocketChannel arg0) throws Exception {arg0.pipeline (). addLast (new TimeServerHandler ());}}}
Package joanna. yan. netty; import java. SQL. date; import io. netty. buffer. byteBuf; import io. netty. buffer. unpooled; import io. netty. channel. channelHandlerContext; import io. netty. channel. channelInboundHandlerAdapter;/*** used to read and write network events * @ author Joanna. yan * @ date November 8, 2017 4:15:13 * // public class TimeServerHandler extends ChannelHandlerAdapter {// public class TimeServerHandler extends ChannelInboundH has been abandoned AndlerAdapter {@ Override public void channelRead (ChannelHandlerContext ctx, Object msg) throws Exception {// ByteBuf is similar to java in JDK. nio. byteBuffer object, but it provides more enhanced and flexible functions. ByteBuf buf = (ByteBuf) msg; byte [] req = new byte [buf. readableBytes ()]; buf. readBytes (req); String body = new String (req, "UTF-8"); System. out. println ("The time server receive order:" + body); String currentTime = "query time order ". equalsIgnoreCase (body )? New Date (System. currentTimeMillis ()). toString (): "bad order"; ByteBuf resp = Unpooled. copiedBuffer (currentTime. getBytes (); ctx. write (resp) ;}@ Override public void channelReadComplete (ChannelHandlerContext ctx) throws Exception {/** ctx. flush (); write the messages in the message sending queue to the SocketChannel and send them to the other party. * In terms of performance, Netty's write method does not directly write messages to SocketChannel to prevent frequent wake-up Selector from sending messages, * To Call The write method, you only need to put the messages to be sent into the sending buffer array. Then, you can call the flush method to write all the messages in the sending buffer into the SocketChannel. */Ctx. flush () ;}@ Override public void exceptionCaught (ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx. close ();}}
3. Netty client development
Package joanna. yan. netty; import io. netty. bootstrap. bootstrap; 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. nioSocketChannel; public class TimeClient {public static Void main (String [] args) throws Exception {int port = 9019; if (args! = Null & args. length> 0) {try {port = Integer. valueOf (args [0]);} catch (Exception e) {// use the default value} new TimeClient (). connect (port, "127.0.0.1");} public void connect (int port, String host) throws Exception {// configure the client NIO thread group EventLoopGroup = new NioEventLoopGroup (); try {Bootstrap B = new Bootstrap (); B. group (group ). channel (NioSocketChannel. class ). option (ChannelOption. TCP_NODELAY, true ). handler (new ChannelInitializer <SocketChannel> () {@ Override protected void initChannel (SocketChannel ch) throws Exception {ch. pipeline (). addLast (new TimeClientHandler () ;}}); // initiate an asynchronous connection operation ChannelFuture f = B. connect (host, port ). sync (); // wait until the client link is closed. channel (). closeFuture (). sync ();} finally {// exit gracefully and release the NIO thread group. shutdownGracefully ();}}}
Package joanna. yan. netty; import java. util. logging. logger; import io. netty. buffer. byteBuf; import io. netty. buffer. unpooled; import io. netty. channel. channelHandlerContext; import io. netty. channel. channelInboundHandlerAdapter; import io. netty. channel. simpleChannelInboundHandler; // public class TimeClientHandler extends ChannelHandlerAdapter {// public class TimeClientHandler extends ChannelInboundHandlerAd has been abandoned Apter {private static final Logger logger = Logger. getLogger (TimeClientHandler. class. getName (); private final ByteBuf firstMessage; public TimeClientHandler () {byte [] req = "query time order ". getBytes (); firstMessage = Unpooled. buffer (req. length); firstMessage. writeBytes (req);}/*** when the TCP link between the client and the server is established successfully, the Netty NIO thread will call the channelActive method and * Send the query time instruction to the server. * // @ Override public void channelActive (ChannelHandlerContext ctx) throws Exception {// send the request information to the server ctx. writeAndFlush (firstMessage);}/*** the channelRead method is called when the server returns a Response Message */@ Override public void channelRead (ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf) msg; byte [] req = new byte [buf. readableBytes ()]; buf. readBytes (req); String body = new String (req, "UTF-8"); System. out. Println ("Now is:" + body);}/*** if an exception occurs, print the exception log and release the client resources. * // @ Override public void exceptionCaught (ChannelHandlerContext ctx, Throwable cause) throws Exception {// release the resource logger. warning ("Unexpected exception from downstream:" + cause. getMessage (); ctx. close ();}}

The use of ChannelInboundHandlerAdapter and SimpleChannelInboundHandler is different:

ChannelInboundHandlerAdapter is a common class, while SimpleChannelInboundHandler <T> is an abstract class. The class inheriting SimpleChannelInboundHandler must implement the channelRead0 method. Callback <T> has an important feature: After the message is read, resources are automatically released. The mechanism of common IM chat software is similar to this. The SimpleChannelInboundHandler class inherits the ChannelInboundHandlerAdapter class, overwrites the channelRead () method, and adds an abstract class. In most scenarios, ChannelInboundHandlerAdapter can be used for processing.

4. Operation and debugging

Server running result:

Client running result:

 

The running result is correct. It can be found that the NIO server and client developed through Netty are very simple. Just a few dozen lines of code can complete the functions that the NIO program needs to complete in a few hundred lines. Netty-based application development not only has simple API usage, fixed development mode, but also has excellent scalability and customization. Later, we will introduce the powerful functions of Netty through more applications.

It should be noted that this example does not take into account the processing of half-outsourcing reading. For function demonstration or testing, the above program is normal, but performance or stress testing is carried out with a slight transformation, it cannot work correctly. An application instance that can correctly process half-packet messages will be provided later.

Netty (2) -- TCP sticky package/package splitting

If this article is helpful to you, please let me know ~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.