Netty5 's architecture is much better than Netty4 's architecture and code, and looks clear.
The following is an example of an improved ECHO server example code based on official website examples.
The addition of Netty in the code Hander,linebasedframedecoder mainly solves the problem of adhesive/unpacking of network transmission. Stringdecoder and Stringencoder primarily address the conversion between Netty Bytebuf and string.
Netty in action also mentions a few caveats: After reading the message, remember to release it, must be released in the finally block (parent class Channelhandleradapter), and the lock is released in the same position, in order to ensure that the release operation must be performed, So why write the message without showing that the reason for the release is that Netty did it for us. Of course, your hander parent class is simplechannelinboundhandler and you don't have to show it, because Netty did it for you.
The following code is primarily to add delimiter (delimiters) to a string.
5.0.0.ALPHA2 version:
/* Copyright (C) 2014-now () the netty5-2015 Authors * * * * Licensed under the Apache License, Version 2.0 (the "Li Cense "); * You are not a use this file except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required by applicable Law or agreed into writing, software * Distributed under the License is distributed on a "as is" BASIS, * without Warra Nties or CONDITIONS of any KIND, either express OR implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.doctor.netty5.ebook.netty_in_action05.common;import java.util.stream.stream;/** * @author Doctor * * @ Time July 6, 2015 */public final class Nettyutil {public static final String end_of_line = "\ n";p ublic static String Appene Ndofline (String ... message) {StringBuilder StringBuilder = new StringBuilder (256); Stream.of (Message). foreachordered (stringbuilder::append); Stringbuilder.append (end_of_line); return stringbuilder.tostring ();}}
Service-Side code:
/* Copyright (C) 2014-present the netty5-2015 Authors * * * * Licensed under the Apache License, Version 2.0 (the " License "); * You are not a use this file except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required by applicable Law or agreed into writing, software * Distributed under the License is distributed on a "as is" BASIS, * without Warra Nties or CONDITIONS of any KIND, either express OR implied. * See the License for the specific language governing permissions and * limitations under the License. */package Com.doctor.netty5.example.echo;import Io.netty.bootstrap.serverbootstrap;import Io.netty.channel.channelfuture;import Io.netty.channel.channelhandleradapter;import Io.netty.channel.channelhandlercontext;import Io.netty.channel.channelinitializer;import Io.netty.channel.nio.nioeventloopgroup;import Io.netty.channel.socket.socketchannel;import Io.netty.channel.socket.nio.NioServerSoCketchannel;import Io.netty.handler.codec.linebasedframedecoder;import Io.netty.handler.codec.string.stringdecoder;import Io.netty.handler.codec.string.stringencoder;import Java.nio.charset.standardcharsets;import com.doctor.netty5.ebook.netty_in_action05.common.nettyutil;/** * @author Doctor * * @time July 6, 2015 */public class Echoserver {private final int port;public Echoserver () {this (8989);} public echoserver (int port) {this.port = port;} /** * * @param args * @throws interruptedexception */public static void Main (string[] args) throws Interruptedexception { New Echoserver (). Start ();} public void Start () throws Interruptedexception {Serverbootstrap bootstrap = new Serverbootstrap (); Nioeventloopgroup Bossgroup = new Nioeventloopgroup (1); Nioeventloopgroup Workergroup = new Nioeventloopgroup (); try {bootstrap.group (Bossgroup, Workergroup). Channel ( Nioserversocketchannel.class). LocalAddress (Port). Childhandler (New channelinitializer<socketchannel> () {@ overrideprotected void InitchanneL (Socketchannel ch) throws Exception {Ch.pipeline (). AddLast (New Linebasedframedecoder (2048)); Ch.pipeline (). AddLast ( New Stringdecoder (Standardcharsets.utf_8)); Ch.pipeline (). AddLast (New Stringencoder (Standardcharsets.utf_8)); Ch.pipeline (). AddLast (New Echoserverhandler ());}); Channelfuture channelfuture = Bootstrap.bind (). sync (); System.out.println (EchoServer.class.getName () + "started and listen on port:" + Channelfuture.channel (). LocalAddress () ); Channelfuture.channel (). Closefuture (). sync (); finally {workergroup.shutdowngracefully (); bossgroup.shutdowngracefully ();}} private static class Echoserverhandler extends Channelhandleradapter {@Overridepublic void Exceptioncaught ( Channelhandlercontext CTX, Throwable cause) throws Exception {cause.printstacktrace (); Ctx.close ();} @Overridepublic void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {System.out.println (msg); Ctx.write (Nettyutil.appenendofline ("Server Returned:", (String) msg)); @Overridepublic void Channelreadcomplete (ChannelHandlercontext ctx) throws Exception {Ctx.flush ();}}}
Client code:
/* Copyright (C) 2014-present the netty5-2015 Authors * * * * Licensed under the Apache License, Version 2.0 (the " License "); * You are not a use this file except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required by applicable Law or agreed into writing, software * Distributed under the License is distributed on a "as is" BASIS, * without Warra Nties or CONDITIONS of any KIND, either express OR implied. * See the License for the specific language governing permissions and * limitations under the License. */package Com.doctor.netty5.example.echo;import Io.netty.bootstrap.bootstrap;import Io.netty.channel.channelfuture;import Io.netty.channel.channelhandleradapter;import Io.netty.channel.channelhandlercontext;import Io.netty.channel.channelinitializer;import Io.netty.channel.nio.nioeventloopgroup;import Io.netty.channel.socket.socketchannel;import Io.netty.channel.socket.nio.NioSocketChannel;Import Io.netty.handler.codec.linebasedframedecoder;import Io.netty.handler.codec.string.stringdecoder;import Io.netty.handler.codec.string.stringencoder;import Io.netty.util.referencecountutil;import Java.nio.charset.standardcharsets;import Java.util.scanner;import Com.doctor.netty5.ebook.netty_in_ action05.common.nettyutil;/** * @author Doctor * * @time July 6, 2015 */public class Echoclient {private final String host; Private final int port;public echoclient () {This ("localhost", 8989);} Public echoclient (String host) {This (host, 8989);} Public Echoclient (String host, int port) {this.host = Host;this.port = port;} /** * @param args * @throws interruptedexception */public static void Main (string[] args) throws interruptedexception {new Echoclient (). Start ();} public void Start () throws Interruptedexception {Nioeventloopgroup workersgroup = new Nioeventloopgroup (1); try { Bootstrap Bootstrap = new Bootstrap (); Bootstrap.group (Workersgroup). Channel (Niosocketchannel.class). Remoteaddress ( Host, Port). Handler (new channelinitializer<socketchannel> () {@Overrideprotected void Initchannel (Socketchannel ch) throws Exception {ch.pipeline (). AddLast (New Linebasedframedecoder (2048)); Ch.pipeline (). AddLast (New Stringdecoder ( Standardcharsets.utf_8)); Ch.pipeline (). AddLast (New Stringencoder (Standardcharsets.utf_8)); Ch.pipeline (). AddLast (New Echoclienthandler ());}); Channelfuture channelfuture = Bootstrap.connect (). sync (); Channelfuture.channel (). Closefuture (). sync (); finally {workersgroup.shutdowngracefully ();}} private static class Echoclienthandler extends Channelhandleradapter {@Overridepublic void Exceptioncaught ( Channelhandlercontext CTX, Throwable cause) throws Exception {cause.printstacktrace (); Ctx.close ();} @Overridepublic void Channelactive (Channelhandlercontext ctx) throws Exception {Ctx.writeandflush ( Nettyutil.appenendofline ("I want to connect ...."); new Thread (New hander (CTX)). Start (); @Overridepublic void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {try {System.out.prINTLN (msg);} finally {//read the message remember to release, then write the message why not do so, because the message Netty automatically released after writing. Its operation see: Defaultchannelhandlerinvoker l331-332, but there is this annotation---promise cancelled//is a lot of netty5 when the official release will be canceled. We can use Simplechannelinboundhandler as the parent class because the release operation has been implemented. Referencecountutil.release (msg);}}} Private static class hander implements Runnable {private Channelhandlercontext CTX = null;private Scanner Scanner = new Sc Anner (system.in);p ublic hander (Channelhandlercontext ctx) {this.ctx = CTX;} @Overridepublic void Run () {while (true) {String nextline = Scanner.nextline (); Ctx.writeandflush ( Nettyutil.appenendofline (nextline));}}}
The client initiates a thread, and the asynchronous operation gets the input string from the console (end of carriage return).
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Netty5 Echo Server Exercises