Objective
As one of the most popular NIO frameworks in the world, Netty is the best in terms of function, performance, robustness, and is validated in many projects, such as message middleware ROCKETMQ, distributed communication Framework Dubbox. Netty internal implementation is complex, but the API provided to the outside world is very simple, easy to let our network processing code and business logic processing code separated, so as to quickly develop network applications.
If you do not know the JAVA Nio,java SOCKET, you can first refer to the blogger's previous blog about this: into the world of Java NiO "," Java NIO Server and client implementation file download "," Java Communication Combat: writing a custom communication protocol for FTP service ".
Analyzing Netty from a code instance
Server-side startup code
Public class main { public static void main (String[] args) { EventLoopGroup bossGroup = New nioeventloopgroup (); // (1) eventloopgroup workergroup = new nioeventloopgroup (); // (2) int port = 8867; try { serverbootstrap b = new serverbootstrap (); // (3) b.group (Bossgroup, workergroup) .channel (Nioserversocketchannel.class) // (4) &nBsp; .childhandler (New ChannelInitializer<SocketChannel> () { // (5) @Override public void initchannel (SocketChannel &NBSP;CH) throws Exception { ch.pipeline (). AddLast (New serverhandler ()); } }) .option (channeloption.so_backlog, 128) // (6) &NBSP;&NBsp; .childoption (ChannelOption.SO_KEEPALIVE, True); // (7) // bind and start to accept incoming connections. channelfuture f = b.bind (port). Sync (); // (8) // Wait until the server socket is closed. // in this example, this does not happen, but you can do that to gracefully // shut down your server. system.out.priNtln ("Start server ...."); F.channel (). Closefuture (). Sync (); System.out.println ("Stop server ..."); } catch ( Interruptedexception e) { E.printstacktrace (); } finally { workergroup.shutdowngracefully (); bossgroup.shutdowngracefully (); system.out.println ("Exit server ...."); } }}
The above roughly reveals the code steps written by the Netty service-side startup, which we will analyze in detail below:
In the original Java socket communication, whether based on Io/nio, essentially the server has 2 jobs to handle: First, accept the client's connection request, and second, process the client's request for communication. In the above code, Netty has abstracted 2 eventloopgroup thread groups (Bossgroup/workergroup) for us to accomplish these 2 tasks.
Before the server starts, it is obvious that some configuration (type of channel, handler of service processing, configuration of some TCP/IP protocol, etc.) is needed, Netty can use Serverbootstrap/bootstrap to server/ Client for configuration.
Bind port, start service, notice the returned object channelfuture, since it is called the future, then guessing is an asynchronous behavior. It is important to note that the channel can be obtained by channelfuture, thus using channels to read, write, close and so on.
With the Bind method, multiple ports can be bound to achieve N clients on the server side of the M port for data communication.
Let's take a look at the handler of the service side for business processing
public class serverhandler extends channelhandleradapter { //whenever new data is received from the client, this method is called when the message is received @Override public void channelread (channelhandlercontext ctx, object msg) throws exception { ByteBuf in = (BYTEBUF) msg; try { // Do something with msg system.out.println ("SERVER&NBSP;GET&NBSP;:" + in.tostring (CharsetUtil.UTF_8)); ChannelFuture channelFuture = ctx.writeandflush (Unpooled.copiedbuffer ("server send time: " + new Date ( )). GetBytes ()); &NBSP;&NBSP;&NAfter the bsp; //server sends the data, close the channel channelfuture.addlistener (Channelfuturelistener.close); } finally { //bytebuf is a reference count object that must be shown to call the release () method to release //or ((BYTEBUF) msg). Release (); referencecountutil.release (msg); The} } //exceptioncaught () event handling method is called when the Throwable object appears //when Netty due to an IO error or when the processor throws an exception when handling an event @Override public void exceptioncaught (Channelhandlercontext ctx, throwable cause) throws exception { // close the connection when an exception is raised. cause.printstacktrace (); ctx.close (); }}
First of all, the service side of the handler inherited the Channelhandleradapter, which is actually reflected in the adapter design mode. Channelhandleradapter implements Channelhandler, if our service side handler directly implements Channelhandler, will need to override a very many APIs, The first is to implement the generic Channelhandler through Channelhandleradapter, and then let the server handler to replicate the specific API.
When a particular event occurs on a channel, a specific method is called to process it, which looks clear.
Netty The data type for network communication is the buffered data type, such as Bytebuf. When we used Bytebuffer to communicate in NiO, we needed to pay extra attention to position's location change, and now Netty, we don't need to care about that.
There are buffers on the client/server side, so we need to be aware that buffer messages are released and refreshed. If read, then need release, if write, only need to flush (flush when the release has been done) to send to each other.
Since Netty is a NIO framework, where operations are asynchronous, the above Writeandflush operation returns the future object, which we can listen to on this future, such as closing the channel when the operation is complete.
Client startup code
Public class client { public static void main (String[] args) { eventloopgroup group = new nioeventloopgroup (); try { bootstrap b = new bootstrap (); b.group (group) .channel (NioSocketChannel.class) .handler (new Channelinitializer<socketchannel> () { @Override &nbSp; public void initchannel (SocketChannel ch) throws exception { channelpipeline p = ch.pipeline (); p.addlast (New clienthandler ()); } }); // Start the client. channelfuture f = b.connect ("127.0.0.1", 8867). sync (); // wait until the connection is closed. f.channel (). Closefuture (). Sync (); } catch (interruptedexception e) { e.printstacktrace (); } finally { // shut down the event loop to terminate all threads. group.shutdowngracefully (); } }}
Here, we mainly look at the differences between the client and server start-up:
First, the client needs only one thread group, and the server requires 2
Second, the service starts the auxiliary class, the client is bootstrap, the server is Serverbootstrap
Third, the server-side channel configuration is Nioserversocketchannel, and the client is Niosocketchannel
Client Business Processing Handler
public class clienthandler extends channelhandleradapter { @ Override public void channelactive (CHANNELHANDLERCONTEXT&NBSP;CTX) Throws exception { ctx.writeandflush ( Unpooled.copiedbuffer (("client send hello "). GetBytes ()); } @Override public void channelread (Channelhandlercontext ctx, &NBSP;OBJECT&NBSP;MSG) throws Exception { bytebuf in = (BYTEBUF) msg; try { // do something with &NBSP;MSG&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SYSTEM.OUT.PRINTLN ("Client get : " + in.tostring (CharsetuTil. Utf_8)); ctx.close (); } finally { //bytebuf is a reference count object that must be shown to call the release () method to release //or ((BYTEBUF) msg). Release (); referencecountutil.release (msg); } }}
Run up
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/8C/94/wKioL1hwq8nSykRsAAAbP6u2-GU304.png "title=" Sogou _ 2017-01-07_16-50-37.png "alt=" Wkiol1hwq8nsykrsaaabp6u2-gu304.png "/>
650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M01/8C/94/wKioL1hwq9XguTjSAAAiN9E-tHQ820.png "title=" Sogou _ 2017-01-07_16-51-05.png "alt=" Wkiol1hwq9xgutjsaaain9e-thq820.png "/>
Have you realized the simplicity and strength of netty?
We'll see you next blog.
This article is from the "Boundless Mind Infinite" blog, please be sure to keep this source http://zhangfengzhe.blog.51cto.com/8855103/1890017
Netty Practice (i): Easy to get started