Messagepack for netty codec

First, let’s talk about the issues that need to be paid attention to

1: The javabean on the sender side must have the annotation  @Message. This annotation should be added to the class. Classes to be serialized can be marked with @Message. All members of the class are serialized. Otherwise, the javabean will not be serialized and will not be received. The javabean on the receiving end can not add this annotation. Both ends of habit will be added.

2. Because of   @Message, javabean does not need to implement the Serializable interface. Of course, there is no problem in implementing it (tested);

3. The sent javabean should exist on both the Client and Server sides, and the names should be exactly the same, and the full class names should be the same. Or directly type it into a separate jar package and put it on both ends;

4. Sender encoding, service decoding. That is, the classes for encoding and decoding do not necessarily have to be present on both ends.

5. There are many questions about messagepack unpacking on the Internet. I found that I did not stick to the package. . . So, this piece is not dealt with. There are many friends who are in need to find them online.

There are also related introductions in the netty authoritative guide.

The pits encountered: (1) The @Message annotation was not added at the beginning (2) The decoded piece of code should be msg.getBytes(msg.readerIndex(), array, 0, length); but it was written as msg.getBytes(msg .readableBytes(), array, 0, length); Causes the decoded msg to have length 0 and no content;

No other issues yet.

Let's look at the specific code. The client side and the server side are two different projects.

The two ends of javabean and encoding and decoding code are the same, here is a copy.

The handler is relatively simple to write and can be modified as needed;

Client-side code:

NettyClient.java
package com.aowin.netty.serial.messagepack;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

public class NettyClient {
    public void connet(){
        EventLoopGroup bosLoup=new NioEventLoopGroup();
        Bootstrap bootstrap=new Bootstrap();
        bootstrap.group(bosLoup)
                .channel(NioSocketChannel.class)
                .handler(new NettyClientInitializer());
        try {
            ChannelFuture future= bootstrap.connect("127.0.0.1",8765).sync();
            UserInfo userInfoArray[]=new UserInfo[3];
            for(int i=0;i<3;i++){
                UserInfo userInfo=new UserInfo();
                userInfo.setName("netty");
                userInfo.setAge(i);
                userInfoArray[i]=userInfo;
            }

           // future.channel().writeAndFlush(Unpooled.copiedBuffer("hello".getBytes()));
            future.channel().writeAndFlush(userInfoArray);
            future.channel().closeFuture().sync();
            bosLoup.shutdownGracefully();
        } catch (InterruptedException e) {
            e.printStackTrace ();
        }
    }

    public static void main(String[] args) {
        NettyClient client=new NettyClient();
        client.connet();
    }
}
 
 
NettyClientHandler.java  
package com.aowin.netty.serial.messagepack;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class NettyClientHandler  extends ChannelHandlerAdapter{
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    }
}
 
 
NettyClientInitializer.java
package com.aowin.netty.serial.messagepack;

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.string.StringDecoder;

public class NettyClientInitializer extends ChannelInitializer{
    @Override
    protected void initChannel(Channel ch) throws Exception {
        //ch.pipeline().addLast(new StringDecoder());
        ch.pipeline().addLast(new MsgPackEncode());
        ch.pipeline().addLast(new MsgPackDecode());
        ch.pipeline().addLast(new NettyClientHandler());

    }
}

Server端的代码:

NettyServer.java

package com.aowin.netty.serial.messagepack;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class NettyServer {
    public void bind() {
        EventLoopGroup bosGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bosGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 1024)
                .option(ChannelOption.SO_SNDBUF, 32 * 1024)
                .option(ChannelOption.SO_RCVBUF, 32 * 1024)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new LoggingHandler(LogLevel.DEBUG))
                .childHandler(new NettyServerInitializer());
        try {
            ChannelFuture future = bootstrap.bind("127.0.0.1", 8765).sync();
            future.channel().closeFuture().sync();
            bosGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        NettyServer server=new NettyServer();
        server.bind();
    }
}
 
 
NettyServerHandler.java
package com.aowin.netty.serial.messagepack;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.List;
import java.util.logging.Logger;

public class NettyServerHandler extends ChannelHandlerAdapter {
    Log logger= LogFactory.getLog(NettyServerHandler.class);
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        List<UserInfo> list= (List<UserInfo>) msg;

        logger.info(list);
        logger.info(list.get(0));
        logger.info(list.get(1));
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    }
}
 
 
NettyServerInitializer.java
package com.aowin.netty.serial.messagepack;

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.string.StringDecoder;

public class NettyServerInitializer extends ChannelInitializer {
    protected void initChannel(Channel ch) throws Exception {
        ch.pipeline().addLast(new MsgPackEncode());
        ch.pipeline().addLast(new MsgPackDecode());
        ch.pipeline().addLast(new NettyServerHandler());
    }
}

下面是两个端都要有的代码:

    解码:

MsgPackDecode.java 

package com.aowin.netty.serial.messagepack;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.msgpack.MessagePack;

import java.util.List;

public class MsgPackDecode extends MessageToMessageDecoder<ByteBuf> {
private Log logger= LogFactory.getLog(MsgPackDecode.class);
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg,
                          List<Object> out) throws Exception {
        logger.info("解码");
        final byte[] array;
        final int length = msg.readableBytes();
        array = new byte[length];
        //msg.getBytes(msg.readableBytes(), array, 0, length);
        msg.getBytes(msg.readerIndex(), array, 0, length);
        MessagePack msgPack = new MessagePack();
        out.add(msgPack.read(array));
        logger.info("解码");
    }

}
 
 

编码:

package com.aowin.netty.serial.messagepack;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.msgpack.MessagePack;

public class MsgPackEncode  extends MessageToByteEncoder<Object> {
    private Log logger= LogFactory.getLog(MsgPackEncode.class);
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out)
            throws Exception {
        logger.info("编码");
        MessagePack msgPack = new MessagePack();
        System.out.println(msg == null);
        byte[] raw = null;
        raw = msgPack.write(msg);
        out.writeBytes(raw);
        logger.info("编码");
    }
}
javaBean:
package com.aowin.netty.serial.messagepack;

import org.msgpack.annotation.Message;

import java.io.Serializable;

//这个注解是加在类上的
@Message
public class UserInfo{
    String name;
    int age;

    public String getName() {
        
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
运行结果:

客户端:


服务端:


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325406708&siteId=291194637