"Netty authoritative Guide" Private protocol development of the operational source code sharing

Source: Internet
Author: User
Tags throwable jboss

Before reading the "Netty authoritative guide" book, the 14th chapter describes how to design and implement a simple private protocol, the content is very good, but the author provides the code fragment has a lot of errors, it is impossible to compile correctly.

For example Marshallingencoder This class is Netty provides a suitable class of JBoss marshalling, its Encode method is protected, not public, And the Channelbufferbyteoutput class used in it is the package class visible, outside cannot be referenced. Netty only so designed, because this tool class can not be used directly externally, but to its internal channelhandler use. It must be inherited if it is to be used externally. But the code in the book is used directly ... Do not know how to compile the pass.

In addition Nettymessageencoder inside the code to calculate the length of the message also has no problem, nettymessagedecoder not set lengthadjustment, can not run successfully, do not know how the results of the book obtained.


Had to modify the code in the book, and run successfully in the local, the implementation of the message structure definition, message encoding and decoding class, JBoss marshalling encoder/decoder extension, Loginreqhandler/ Loginreshandler, Nettyserver, Nettyclient. Now put the code out, the needy students can take to run a local run.


Defining message nettymessage and message header headers

Package Com.netty.test.netty4;public class Nettymessage {private header header;private Object body;public header GetHeader () {return header;} public void SetHeader (header header) {This.header = header;} Public Object GetBody () {return body;} public void Setbody (Object body) {this.body = body;} Public String toString () {return "nettymessage [header=" + header + "]";}}

Package Com.netty.test.netty4;import Java.util.hashmap;import Java.util.map;public class Header {private int crccode = 0xabef0101;private int length;private long sessionid;private byte type;private byte priority;private Map<String, object> attachment = new hashmap<string, object> ();p ublic int Getcrccode () {return crccode;} public void Setcrccode (int crccode) {this.crccode = Crccode;} public int GetLength () {return length;} public void setLength (int length) {this.length = length;} Public long GetSessionID () {return sessionID;} public void Setsessionid (long SessionID) {This.sessionid = SessionID;} Public byte GetType () {return type;} public void SetType (byte type) {This.type = type;} Public byte getpriority () {return priority;} public void SetPriority (Byte priority) {this.priority = priority;} Public map<string, Object> getattachment () {return attachment;} public void Setattachment (map<string, object> attachment) {this.attachment = attachment;} Public String toString () {return "Header [crccode=" + Crccode + ", length=" + length + ", sessionid=" + sessionid+ ", type=" + Type + ", priority=" + prio Rity + ", attachment=" + Attachment + "]";}}

Extending Marshallingencoder and Marshallingdecoder, programming the protected method public can invoke the

Package Com.netty.test.netty4;import Io.netty.buffer.bytebuf;import Io.netty.channel.channelhandlercontext;import Io.netty.handler.codec.marshalling.marshallerprovider;import Io.netty.handler.codec.marshalling.marshallingencoder;public class Nettymarshallingencoder extends Marshallingencoder{public Nettymarshallingencoder (Marshallerprovider provider) {super (provider);} public void Encode (Channelhandlercontext ctx, Object msg, bytebuf out) throws Exception{super.encode (CTX, MSG, out);}}

Package Com.netty.test.netty4;import Io.netty.buffer.bytebuf;import Io.netty.channel.channelhandlercontext;import Io.netty.handler.codec.marshalling.marshallingdecoder;import Io.netty.handler.codec.marshalling.unmarshallerprovider;public class Nettymarshallingdecoder extends Marshallingdecoder{public Nettymarshallingdecoder (Unmarshallerprovider provider) {super (provider);} Public Nettymarshallingdecoder (unmarshallerprovider provider, int maxobjectsize) {super (provider, maxobjectsize);} Public Object decode (Channelhandlercontext ctx, bytebuf in) throws Exception {return Super.decode (CTX, in);}}

Define the Marshallingcodecfactory factory class to get the JBoss marshalling class

Package Com.netty.test.netty4;import Io.netty.handler.codec.marshalling.defaultmarshallerprovider;import Io.netty.handler.codec.marshalling.defaultunmarshallerprovider;import Io.netty.handler.codec.marshalling.marshallerprovider;import Io.netty.handler.codec.marshalling.marshallingdecoder;import Io.netty.handler.codec.marshalling.unmarshallerprovider;import Org.jboss.marshalling.marshallerfactory;import Org.jboss.marshalling.marshalling;import Org.jboss.marshalling.marshallingconfiguration;public Class marshallingcodecfactory {public static Nettymarshallingdecoder Buildmarshallingdecoder () {marshallerfactory Marshallerfactory = Marshalling.getprovidedmarshallerfactory ("Serial"); Marshallingconfiguration configuration = new Marshallingconfiguration (); configuration.setversion (5); Unmarshallerprovider Provider = new Defaultunmarshallerprovider (marshallerfactory, configuration); Nettymarshallingdecoder decoder = new Nettymarshallingdecoder (provider, 1024x768); return decoder;} public static NettymarShallingencoder Buildmarshallingencoder () {Marshallerfactory marshallerfactory = Marshalling.getprovidedmarshallerfactory ("Serial"); Marshallingconfiguration configuration = new Marshallingconfiguration (); configuration.setversion (5); Marshallerprovider Provider = new Defaultmarshallerprovider (marshallerfactory, configuration); Nettymarshallingencoder encoder = new Nettymarshallingencoder (provider); return encoder;}}

Define the encoder of the Nettymessage, note the method of calculating the length of the message, and finally pass it out

Package Com.netty.test.netty4;import Io.netty.buffer.bytebuf;import Io.netty.buffer.unpooled;import Io.netty.channel.channelhandlercontext;import Io.netty.handler.codec.messagetomessageencoder;import Java.util.list;import Java.util.map;public class Nettymessageencoder extends messagetomessageencoder< Nettymessage>{private nettymarshallingencoder marshallingencoder;public Nettymessageencoder () { Marshallingencoder = Marshallingcodecfactory.buildmarshallingencoder ();} @Overrideprotected void Encode (Channelhandlercontext ctx, Nettymessage msg,list<object> out) throws Exception {if (msg = = NULL | | Msg.getheader () = = null) {throw new Exception ("The ENCODE message is null");} Bytebuf sendbuf = Unpooled.buffer (); Sendbuf.writeint (Msg.getheader (). Getcrccode ()); Sendbuf.writeint (Msg.getHeader (). GetLength ()); Sendbuf.writelong (Msg.getheader (). GetSessionID ()); Sendbuf.writebyte (Msg.getheader (). GetType ()) ; Sendbuf.writebyte (Msg.getheader (). getpriority ()); Sendbuf.writeint (Msg.getheader (). GetattachmENT (). Size ()); String key = null;byte[] Keyarray = null;object value = Null;for (map.entry<string, object> param:msg.getHeader (). GE Tattachment (). EntrySet ()) {key = Param.getkey (); Keyarray = Key.getbytes ("UTF-8"); Sendbuf.writeint (keyarray.length); Sendbuf.writebytes (keyarray); value = Param.getvalue (); Marshallingencoder.encode (CTX, value, SENDBUF);} Key = Null;keyarray = Null;value = Null;if (msg.getbody () = null) {Marshallingencoder.encode (CTX, Msg.getbody (), SendBuf) ;} Sendbuf.writeint (0);//The length of the 4th byte written to buffer int readablebytes = Sendbuf.readablebytes (); Sendbuf.setint (4, readablebytes);//Add the message to the list to pass to the next handler Out.add (SENDBUF);}}

Define the Nettymessagedecoder class, pay attention to set several important parameters of lengthfieldbasedframedecoder, directly affect the decoding result

Package Com.netty.test.netty4;import Io.netty.buffer.bytebuf;import Io.netty.channel.channelhandlercontext;import Io.netty.handler.codec.lengthfieldbasedframedecoder;import Java.util.hashmap;import Java.util.Map;public Class Nettymessagedecoder extends Lengthfieldbasedframedecoder{private nettymarshallingdecoder marshallingDecoder;public Nettymessagedecoder (int maxframelength, int lengthfieldoffset,int lengthfieldlength,int lengthAdjustment, int Initialbytestostrip) {super (maxframelength, Lengthfieldoffset, Lengthfieldlength, Lengthadjustment, Initialbytestostrip); marshallingdecoder = Marshallingcodecfactory.buildmarshallingdecoder ();} Public Object decode (Channelhandlercontext ctx, bytebuf in) throws exception{bytebuf frame = (bytebuf) super.decode (CTX, I n); if (frame = = null) {return null;} Nettymessage message = new Nettymessage (); Header Header = new header (); Header.setcrccode (Frame.readint ()); Header.setlength (Frame.readint ()); Header.setsessionid (Frame.readlong ()); Header.settype (Frame.reaDbyte ()); Header.setpriority (Frame.readbyte ()); int size = Frame.readint (); if (Size > 0) {map<string, object> Attach = new hashmap<string, object> (size), int keySize = 0;byte[] Keyarray = null; String key = null;for (int i=0; i<size; i++) {keySize = Frame.readint (); keyarray = new Byte[keysize];in.readbytes (Keyarr ay); key = new String (Keyarray, "UTF-8"); Attach.put (Key, Marshallingdecoder.decode (CTX, frame));} Key = Null;keyarray = Null;header.setattachment (attach);} if (frame.readablebytes () > 0) {message.setbody (Marshallingdecoder.decode (CTX, frame));} Message.setheader (header); return message;}}

Define Loginauthreqhandler, the client sends the requested business Channelhandler

package com.netty.test.netty4;import Io.netty.channel.channelhandleradapter;import Io.netty.channel.channelhandlercontext;public class Loginauthreqhandler extends Channelhandleradapter {public void Channelactive (Channelhandlercontext ctx) throws Exception {Ctx.writeandflush (Buildloginreq ());} public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {nettymessage message = (nettymessage) msg ; if (message.getheader () = null && Message.getheader (). GetType () = = (byte) 2) {System.out.println ("Received From server Response ");} Ctx.firechannelread (msg);} Private Nettymessage Buildloginreq () {nettymessage message = new Nettymessage (); Header Header = new header (), Header.settype ((byte) 1), Message.setheader (header), Message.setbody ("It is Request"); return message;} public void Channelreadcomplete (Channelhandlercontext ctx) throws Exception {Ctx.flush ();} public void Exceptioncaught (Channelhandlercontext ctx, throwable cause) {ctx.close ();}} 

Define the Loginauthresphandler class, server-side response to login's business Channelhandler

Package Com.netty.test.netty4;import Io.netty.channel.channelhandleradapter;import Io.netty.channel.channelhandlercontext;public class Loginauthresphandler extends Channelhandleradapter {public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {nettymessage message = (nettymessage) msg;if ( Message.getheader ()! = null && message.getheader (). GetType () = = (byte) 1) {System.out.println ("Login is OK"); String BODY = (string) message.getbody (); SYSTEM.OUT.PRINTLN ("recevied message body from client is" + body);} Ctx.writeandflush (Buildloginresponse ((byte) 3)); Private Nettymessage Buildloginresponse (byte result) {Nettymessage message = new Nettymessage (); Header Header = new header (), Header.settype ((Byte) 2), Message.setheader (header), message.setbody (result), return Message;} public void Channelreadcomplete (Channelhandlercontext ctx) throws Exception {Ctx.flush ();} public void Exceptioncaught (Channelhandlercontext ctx, throwable cause) {ctx.close ();}}

Define Nettyclient

Package Com.netty.test.netty4;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;import Io.netty.handler.codec.linebasedframedecoder;import Io.netty.handler.codec.string.stringdecoder;public class Nettyclient {public void Connect (string remoteserver, int Port) throws Exception {Eventloopgroup workergroup = new Nioeventloopgroup (); try {Bootstrap b = new Bootstrap (); B.group (wo Rkergroup). Channel (Niosocketchannel.class). Handler (new Childchannelhandler ()); Channelfuture f = b.connect (Remoteserver,port). sync (); System.out.println ("Netty time Client connected at Port" + port); F.channel (). Closefuture (). sync (); finally {workergroup.shutdowngracefully ();}} public static class Childchannelhandler Extendschannelinitializer<socketchannel> {@Overrideprotected void Initchannel (Socketchannel ch) throws Exception {//- 8 means lengthadjustment, the decoder intercepts bytes from 0, and contains the message header Ch.pipeline (). AddLast (New Nettymessagedecoder (1024 * 1024, 4, 4,-8, 0)). AddLast (New Nettymessageencoder ()). AddLast (New Loginauthreqhandler ());}} public static void Main (string[] args) {try {new nettyclient (). Connect ("127.0.0.1", 9080);} catch (Exception e) {e.printst Acktrace ();}}}

Define Nettyserver

Package Com.netty.test.netty4;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;import Io.netty.handler.codec.linebasedframedecoder;import Io.netty.handler.codec.string.stringdecoder;public Class nettyserver {public void bind (int port) throws Exception {Eventloopgroup bossgroup = new Nioeventloopgroup (); Eventloopgroup Workergroup = new Nioeventloopgroup (); try {serverbootstrap b = new Serverbootstrap (); B.group (BossGroup, Workergroup). Channel (nioserversocketchannel.class). Option (Channeloption.so_backlog, 1024x768). Childhandler (New Childchannelhandler ()); Channelfuture f = b.bind (port). sync (); System.out.println ("Netty time Server started at Port" + port); F.channel (). Closefuture (). sync ();} finally {bOssgroup.shutdowngracefully (); workergroup.shutdowngracefully ();}} public static class Childchannelhandler extendschannelinitializer<socketchannel> {@Overrideprotected void Initchannel (Socketchannel ch) throws Exception {Ch.pipeline (). AddLast (New Nettymessagedecoder (1024 * 1024, 4, 4,-8, 0)). AddLast (New Nettymessageencoder ()). AddLast (New Loginauthresphandler ());}} public static void Main (string[] args) {try {new nettyserver (). bind (9080);} catch (Exception e) {e.printstacktrace ();}}}

Operation Result:

Server-side:


Client:





"Netty authoritative Guide" Private protocol development of the operational source code sharing

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.