Netty4 actual combat-coding and decoding technology

Source: Internet
Author: User

Often we are accustomed to calling encoding (Encode) serialization (serialization), which serializes objects into byte arrays for network transmissions, data persistence, or other purposes.

Conversely, decoding (Decode) is called deserialization (deserialization), which restores a byte array read from a network, disk, etc. to the original object (usually a copy of the original object) to facilitate subsequent business logic operations. Java Serialization

The first serialization or codec technology that most Java programmers are exposed to is the Java Default-provided serialization mechanism. The Java object that needs to be serialized can only implement the Java.io.Serializable interface and generate a serialization ID, which is serializable and deserialized through Java.io.ObjectInput and Java.io.ObjectOutput. other serialization Frameworks

The Java default serialization mechanism is inefficient and the serialized code stream is larger, so there are a number of excellent Java serialization frameworks emerging, such as Hessian, PROTOBUF, Thrift, Protostuff, Kryo, Msgpack, Avro, FST Wait a minute. Extended Netty Decoder

Netty provides a io.netty.handler.codec.MessageToByteEncoder and Io.netty.handler.codec.ByteToMessageDecoder interface to facilitate our extended codec.

In order to extend the serialization framework more conveniently, we first define the serializer interface:

Import java.io.IOException;

/**
 * @author Ricky Fung * * Public
Interface Serializer {

    byte[] encode (Object msg) throws ioexception;< C5/><t> T decode (byte[] buf, class<t> type) throws IOException;

Define Serializer Factory:

Import Com.mindflow.netty4.serialization.hessian.HessianSerializer;

/**
 * @author Ricky Fung * * Public
class Serializerfactory {public

    static serializer Getserializer () {return
        new Hessianserializer ();
    }
}

Next, we use the serializer interface defined above in Netty decoder, as follows:

Import Com.mindflow.netty4.serialization.Serializer;
Import Com.mindflow.netty4.serialization.SerializerFactory;
Import Io.netty.buffer.ByteBuf;
Import Io.netty.channel.ChannelHandlerContext;
Import Io.netty.handler.codec.LengthFieldBasedFrameDecoder;
Import Org.slf4j.Logger;

Import Org.slf4j.LoggerFactory;

Import java.io.IOException; /** * ${description} * * @author Ricky Fung/public class Nettymessagedecoder<t> extends

    Decoder {private Logger Logger = Loggerfactory.getlogger (GetClass ());

    To determine whether the data transmitted by the transmitting client is transmitted according to the Protocol, and the header information should be byte+byte+int = 1+1+4 = 6 private static final int header_size = 6;
    Private Serializer Serializer = Serializerfactory.getserializer ();

    Private class<t> Clazz;
                               Public Nettymessagedecoder (class<t> clazz, int maxframelength, int lengthfieldoffset,
    int lengthfieldlength) throws IOException {super (maxframelength, Lengthfieldoffset, lengthfieldlength);    This.clazz = Clazz;

        } @Override protected Object decode (Channelhandlercontext ctx, bytebuf in) throws Exception {
        if (In.readablebytes () < header_size) {return null;

        } in.markreaderindex ();
        Note that during the reading process, the Readindex pointer also moves the byte type = In.readbyte ();

        BYTE flag = In.readbyte ();

        int datalength = In.readint ();

        Logger.info ("Read type:{}, flag:{}, length:{}", type, flag, datalength);
            if (In.readablebytes () < datalength) {Logger.error ("body length < {}", datalength);
            In.resetreaderindex ();
        return null;
        } byte[] data = new Byte[datalength];

        In.readbytes (data);
        try{return Serializer.decode (data, clazz);
        catch (Exception e) {throw new RuntimeException ("Serializer decode error"); }
    }
}

Nettymessageencoder.java

Import Com.mindflow.netty4.serialization.Serializer;
Import Com.mindflow.netty4.serialization.SerializerFactory;
Import Io.netty.buffer.ByteBuf;
Import Io.netty.channel.ChannelHandlerContext;
Import Io.netty.handler.codec.MessageToByteEncoder;
Import Org.slf4j.Logger;

Import Org.slf4j.LoggerFactory; /** * ${description} * * * @author Ricky Fung/Public final class Nettymessageencoder<t> extends

    Tobyteencoder {private Logger Logger = Loggerfactory.getlogger (GetClass ());
    Private final byte type = 0X00;

    Private final byte flag = 0x0f;
    Private Serializer Serializer = Serializerfactory.getserializer ();
    Private class<t> Clazz;
    Public Nettymessageencoder (class<t> clazz) {this.clazz = Clazz; @Override protected void Encode (Channelhandlercontext ctx, Object msg, bytebuf out) t
            Hrows Exception {try {out.writebyte (type);

       Out.writebyte (flag);     byte[] data = Serializer.encode (msg);
            Out.writeint (data.length);

            Out.writebytes (data);
        Logger.info ("Write type:{}, flag:{}, length:{}", type, flag, data.length);
        catch (Exception e) {e.printstacktrace (); }

    }
}

Service side:

Import Com.mindflow.netty4.serialization.model.Request;
Import Com.mindflow.netty4.serialization.model.Response;
Import Io.netty.bootstrap.ServerBootstrap;
Import io.netty.channel.*;
Import Io.netty.channel.nio.NioEventLoopGroup;
Import Io.netty.channel.socket.SocketChannel;
Import Io.netty.channel.socket.nio.NioServerSocketChannel;
Import Io.netty.handler.logging.LogLevel;
Import Io.netty.handler.logging.LoggingHandler;
Import Org.slf4j.Logger;
Import Org.slf4j.LoggerFactory;

Import java.io.IOException;

    /** * @author Ricky Fung * * public class Nettyserver {private Logger Logger = Loggerfactory.getlogger (GetClass ()); public void bind () throws Exception {//config server-side NIO thread Group Eventloopgroup bossgroup = new Nioeventloopgrou
        P (1);
        Eventloopgroup Workergroup = new Nioeventloopgroup ();
        Serverbootstrap B = new Serverbootstrap (); B.group (Bossgroup, Workergroup). Channel (nioserversocketchannel.class). Option (Channeloption.so_backlog(handler). (New Logginghandler (Loglevel.info)). Childhandler (New Channelinitializer&lt ;
                            Socketchannel> () {@Override public void Initchannel (Socketchannel ch) Throws IOException {Ch.pipeline (). AddLast (NE
                        W nettymessagedecoder<> (Request.class,1<<20, 2, 4));
                        Ch.pipeline (). AddLast (New Nettymessageencoder (Response.class));
                    Ch.pipeline (). AddLast (New Nettyserverhandler ());

        }
                });
        Bind port, synchronization waits for success channelfuture future = B.bind (Constants.host, constants.port). sync ();

        Logger.info ("Netty Server start OK host:{}, port:{}", Constants.host, Constants.port);
    Future.channel (). Closefuture (). sync (); Class Nettyserverhandler extends Simplechannelinboundhandler<request> {@OveRride protected void channelRead0 (Channelhandlercontext context, request request) throws Exception {
            Logger.info ("RPC server receive request id:{}", Request.getid ());
        Processing request Processrpcrequest (context, request);
            @Override public void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {
        Logger.error ("Catch exception", cause); } private void Processrpcrequest (final channelhandlercontext context, final request request) {Respons
        E response = new response ();
        Response.setid (Request.getid ());
        Response.setresult ("echo" +request.getmessage ());
    Context.writeandflush (response);
    public static void Main (string[] args) throws Exception {new Nettyserver (). bind (); }

}

Client:

Import Com.mindflow.netty4.serialization.model.Request;
Import Com.mindflow.netty4.serialization.model.Response;
Import Io.netty.bootstrap.Bootstrap;
Import io.netty.channel.*;
Import Io.netty.channel.nio.NioEventLoopGroup;
Import Io.netty.channel.socket.SocketChannel;
Import Io.netty.channel.socket.nio.NioSocketChannel;
Import Org.slf4j.Logger;

Import Org.slf4j.LoggerFactory;

Import java.net.InetSocketAddress; /** * ${description} * * @author Ricky Fung/public class Nettyclient {private Logger Logger = LOGGERFACTORY.G

    Etlogger (GetClass ());

    Private Eventloopgroup group = new Nioeventloopgroup (); public void Connect (int port, String host) throws Exception {//Configure client NiO thread group try {Bootstrap
            b = new Bootstrap ();
                    B.group (Group). Channel (niosocketchannel.class). Option (Channeloption.tcp_nodelay, True) . Handler (new channelinitializer<socketchannel> () {@Override
                        public void Initchannel (Socketchannel ch) throws Exception { Ch.pipeline (). AddLast (New nettymessagedecoder<response>
                            (Response.class, 1024 * 1024, 2, 4));
                            Ch.pipeline (). AddLast (New nettymessageencoder<request> (Request.class));
                        Ch.pipeline (). AddLast (New Nettyclienthandler ());
            }
                    });

            Initiates an asynchronous connection operation channelfuture future = B.connect (host, port). sync ();
                if (future.awaituninterruptibly (5000)) {Logger.info ("Client Connect host:{}, port:{}", host, Port);
                    if (Future.channel (). IsActive ()) {Logger.info ("Start sending messages");
                        for (int i=0; i<100; i++) {Request Req = new request ();
                       Req.setid ((long) i); Req.setmessage ("Hello World");
                    Future.channel (). Writeandflush (req);
                } logger.info ("Send Message complete"); }} and finally {}} class Nettyclienthandler extends Simplechannelinboundhandler&lt ; response> {@Override protected void channelRead0 (Channelhandlercontext channelhandlercontext, respons
            E msg) throws Exception {final Response Response = msg;
        Logger.info ("RPC client receive response id:{}", Response.getid ());
            @Override public void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {
        Logger.error ("Catch exception", cause); }/** * @param args * @throws Exception/public static void main (string[] args) throws exc
    eption {new Nettyclient (). Connect (Constants.port, constants.host); }
}
reference materials

Analysis of Netty Coding and decoding framework of Netty series

Java Depth Adventure (10)--java object serialization and RMI source download

Https://github.com/TiFG/netty4-in-action/tree/master/netty4-serialization-demo

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.