MessagePack编解码

MessagePack Java 模块 GitHub 开源地址:https://github.com/msgpack/msgpack-java

        <dependency>
            <groupId>org.msgpack</groupId>
            <artifactId>msgpack</artifactId>
            <version>0.6.12</version>
        </dependency>
      <dependency>
            <groupId>org.msgpack</groupId>
            <artifactId>msgpack-core</artifactId>
            <version>0.9.0</version>
        </dependency>
import org.msgpack.MessagePack;
import org.msgpack.core.MessageBufferPacker;
import org.msgpack.core.MessageUnpacker;
import org.msgpack.template.Templates;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MessagePackDemo1 {
    public static void main(String...args) throws IOException {
        List<String> src = new ArrayList<>();
        src.add("msgpack");
        src.add("kumofs");
        src.add("viver");
        // msgpack 使用
        MessagePack messagePack = new MessagePack();
        // serialize
        byte[] raw = messagePack.write(src);
        // deserialize
        List<String> dst = messagePack.read(raw, Templates.tList(Templates.TString));
        System.out.println(dst.get(0));
        System.out.println(dst.get(1));
        System.out.println(dst.get(2));

        // msgpack-core 使用
        //数据打包
        MessageBufferPacker packer = org.msgpack.core.MessagePack.newDefaultBufferPacker();
        packer.packArrayHeader(src.size());
        for (String s : src) {
            packer.packString(s);
        }
        packer.close();
        byte[] raw1 = packer.toMessageBuffer().toByteArray();

        // 数据解包
        MessageUnpacker unpacker = org.msgpack.core.MessagePack.newDefaultUnpacker(raw1);
        int i = unpacker.unpackArrayHeader();
        List<String> dst1 = new ArrayList<>();
        for (int j = 0; j < i; j++) {
            dst1.add(unpacker.unpackString());
        }
        System.out.println(dst1.get(0));
        System.out.println(dst1.get(1));
        System.out.println(dst1.get(2));
    }
}

MessagePack 编/解码器 使用

UserInfo

import org.msgpack.annotation.Message;

import java.io.Serializable;
import java.nio.ByteBuffer;

@Message
public class UserInfo implements Serializable {
    private String userName;
    private int userId;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }import org.msgpack.annotation.Message;

import java.io.Serializable;
import java.nio.ByteBuffer;

@Message
public class UserInfo implements Serializable {
    private String userName;
    private int userId;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }
}

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.msgpack.MessagePack;

import java.util.List;

/**
 * Msgpack 解码器
 */
public class MsgpackDecoder extends MessageToMessageDecoder<ByteBuf> {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        final byte[] array;
        final int length = msg.readableBytes();
        array = new byte[length];
        msg.getBytes(msg.readerIndex(), array, 0, length);
        MessagePack messagePack = new MessagePack();
        out.add(messagePack.read(array));
    }
}


import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.msgpack.MessagePack;

/**
 * Msgpack 编码器
 * 将Object类型的对象编码为byte数组,然后写入ByteBuf中
 */
public class MsgpackEncoder extends MessageToByteEncoder<Object> {

    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
        MessagePack messagePack = new MessagePack();
        byte[] raw = messagePack.write(msg);
        out.writeBytes(raw);
    }
}


import com.fly.demo.decoder.MsgpackDecoder;
import com.fly.demo.encoder.MsgpackEncoder;
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.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.net.InetSocketAddress;

/**
 * Msgpack 编/解码器 使用
 */
public class MsgPackEchoServer {
    public static void main(String...args) throws InterruptedException {
        EventLoopGroup parent = new NioEventLoopGroup();
        EventLoopGroup child = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(parent, child)
                    .localAddress(new InetSocketAddress(8080))
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // LengthFieldBasedFrameDecoder处理半包消息
                            // 公式: 发送数据包长度 = 长度域的值 + lengthFieldOffset + lengthFieldLength + lengthAdjustment
                            ch.pipeline().addLast("frameDecoder" , new LengthFieldBasedFrameDecoder(
                                            65535, //发送的数据帧最大长度
                                            0, //长度域的开始地方
                                            2,//定义的长度域的长度
                                            0, // = 数据包长度 - lengthFieldOffset - lengthFieldLength - 长度域的值
                                            2 //解码过程中,没有丢弃前2位
                                    ));
                            ch.pipeline().addLast("msgpack decoder", new MsgpackDecoder());
                            // LengthFieldPrepender将在ByteBuf之前增加2个字节的消息长度字段
                            ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(2));
                            ch.pipeline().addLast("msgpack encoder", new MsgpackEncoder());

                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    });
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        }finally {
            parent.shutdownGracefully().sync();
            child.shutdownGracefully().sync();
        }
    }

    @ChannelHandler.Sharable
    private static class EchoServerHandler extends ChannelInboundHandlerAdapter{

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            System.out.println("Server receive the msgpack message : " + msg);
            ctx.writeAndFlush(msg);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }
}


import com.fly.demo.decoder.MsgpackDecoder;
import com.fly.demo.encoder.MsgpackEncoder;
import com.fly.demo.serial.UserInfo;
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 io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;

import java.net.InetSocketAddress;

/**
 * Msgpack 编/解码器 使用
 */
public class MsgPackEchoClient {
    public static void main(String... args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .remoteAddress(new InetSocketAddress(8080))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(65535, 0, 2, 0, 2));
                            ch.pipeline().addLast("msgpack decoder", new MsgpackDecoder());
                            ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(2));
                            ch.pipeline().addLast("msgpack encoder", new MsgpackEncoder());

                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            ChannelFuture f = b.connect().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }

    private static class EchoClientHandler extends ChannelInboundHandlerAdapter {
        final int sendNumber = 10;

        private UserInfo[] getUserArray(int userNum) {
            UserInfo[] userInfos = new UserInfo[userNum];
            UserInfo userInfo = null;
            for (int i = 0; i < userNum; i++) {
                userInfo = new UserInfo();
                userInfo.setUserId(i);
                userInfo.setUserName("ABCDEFG-->" + i);
                userInfos[i] = userInfo;
            }
            return userInfos;
        }


        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            UserInfo[] userInfos = getUserArray(sendNumber);
            for (UserInfo infoE : userInfos) {
                ctx.writeAndFlush(infoE);
            }
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            System.out.println("Client receive the msgpack message : " + msg);
        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.flush();
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }
}

posted @ 2021-09-27 08:56  fly_bk  阅读(603)  评论(0)    收藏  举报