Encoder: Handles outbound data and converts message objects into byte arrays.

Decoder: Handles inbound data and converts byte arrays into message objects.

Note: Since the actual transmission in the network channel is a binary sequence of bytes, for outbound data, the last OutboundHandler to process the data must send data in type ByteBuf.

Similarly, for an inbound message, the first InboundHandler to receive the message must receive data of type ByteBuf.

There are two Handler chains in the Pipline of a Channel, the OutboundHandler chain for the outbound data and the InboundHandler chain for the inbound data. head —–>tail

Pipeline ().addlast () is added at the end, and pipeline().addfirst () is added at the head.

Netty provides many codecs out of the box:

  • StringEncoderString encoder
  • StringDecoderString decoder
  • ObjectEncoderObject encoder
  • ObjectDecoderObject decoder
  • FixedLengthFrameDecoderFixed length decoder
  • LineBasedFrameDecoderA decoder that ends with a newline character
  • DelimiterBasedFrameDecoderSpecifies a decoder for message separators
  • LengthFieldBasedFrameDecoderLength based universal decoder

The code field

We use Netty to implement an Echo server that only receives messages from the client and returns them to the client.

Introduction of depend on

Ty < dependency > < groupId > io.net < / groupId > < artifactId > netty -all < / artifactId > < version > 4.1.50. The Final < / version > </dependency>Copy the code

The service side EhcoServer

public class Server {
    public void start(a) {
        NioEventLoopGroup boss = new NioEventLoopGroup(1);
        NioEventLoopGroup worker = new NioEventLoopGroup(1);
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boss, worker)
                .localAddress(9999)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                ch.pipeline().addLast(newEchoInboundHandler()); }}); ChannelFuture future =null;
        try {
            future = bootstrap.bind().sync();
            System.out.println("Server started successfully, listening port:" + future.channel().localAddress());
            // Wait for the server listening port to close
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // Close gracefullyboss.shutdownGracefully(); worker.shutdownGracefully(); }}public static void main(String[] args) {
        newServer().start(); }}Copy the code
public class EchoInboundHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf = (ByteBuf) msg; ctx.writeAndFlush(byteBuf); }}Copy the code

The client

public class Client {
    Bootstrap bootstrap = new Bootstrap();

    public Client(a){
        NioEventLoopGroup worker = new NioEventLoopGroup();
        bootstrap.group(worker)
                .channel(NioSocketChannel.class)
                .remoteAddress("127.0.0.1".9999);
    }
    public void send(String msg){
        try {
            Channel channel = bootstrap.connect().sync().channel();
            System.out.println("Client sends message:" + msg);
            channel.writeAndFlush(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{}}}Copy the code

CASE1 does not use any encoder to send messages

public void send(String msg){
        try {
            Channel channel = bootstrap.connect().sync().channel();
            System.out.println("Client sends message:" + msg);
            channel.writeAndFlush(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{}}Copy the code

Without using an encoder, you need to manually convert the message to ByteBuf when sending the message, such as Unpooled. CopiedBuffer (MSG, charsetutil.utf_8)

CASE2 useStringEncoder

public void send(String msg){
        try {
            Channel channel = bootstrap.connect().sync().channel();
            channel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
            System.out.println("Client sends message:" + msg);
            channel.writeAndFlush(msg);
        } catch(InterruptedException e) { e.printStackTrace(); }}Copy the code

Through the channel. Pipeline (.) addLast (new StringEncoder (CharsetUtil. UTF_8)); When you add a String encoder, you can send String data directly.

channel.writeAndFlush(msg);

CASE3 custom encoder

Convert the entity class Person to Json and send it

@Data
public class Person {
    private String name;
    private int age;
}
Copy the code

inheritanceMessageToMessageEncoder

public class JsonEncoder extends MessageToMessageEncoder<Person> {
    @Override
    protected void encode(ChannelHandlerContext ctx, Person person, List<Object> out) throws Exception {
        byte[] bytes = JSON.toJSONBytes(person); ByteBuf byteBuf = Unpooled.buffer(bytes.length); byteBuf.writeBytes(bytes); out.add(byteBuf); }}Copy the code

Send an entity-class message

public void send(Person person){
        try {
            Channel channel = bootstrap.connect().sync().channel();
            channel.pipeline().addLast(new JsonEncoder());
            channel.writeAndFlush(person);
        } catch(InterruptedException e) { e.printStackTrace(); }}Copy the code